牽線搭橋澜沟,『橋接模式』

目錄:設(shè)計模式之小試牛刀
源碼路徑:Github-Design Pattern


定義:(Bridge Pattern)

將抽象和實現(xiàn)解耦够坐,使得兩者可以獨(dú)立地變化托嚣。

類圖:

橋接模式通用類圖

啟示:

一個產(chǎn)品的研發(fā)损趋,流程主要包括需求分析患久、產(chǎn)品設(shè)計、制定計劃浑槽、任務(wù)安排蒋失、進(jìn)度把控、產(chǎn)品發(fā)布桐玻、后期運(yùn)維篙挽。

按照我們一般的設(shè)計思路,我們可能會如下設(shè)計:

一般的設(shè)計思路

定義一個抽象的ProjectManager類镊靴,用來定義項目的開發(fā)流程铣卡,不同的項目通過繼承來實現(xiàn)具體的流程链韭。每增加新的項目,就只需要繼承該類重新實現(xiàn)即可煮落。但這僅適用于某個單一角色對產(chǎn)品的管理敞峭。

我們知道一個IT公司的組織架構(gòu)一般由CEO、產(chǎn)品經(jīng)理蝉仇、項目經(jīng)理和員工組成旋讹。CEO負(fù)責(zé)整個公司運(yùn)行項目的整體把控,產(chǎn)品經(jīng)理負(fù)責(zé)公司的某一條產(chǎn)品線轿衔,項目經(jīng)理則負(fù)責(zé)產(chǎn)品線中的某個項目的開發(fā)管理骗村,而員工就是負(fù)責(zé)項目的開發(fā)工作。

作為一名項目經(jīng)理呀枢,職責(zé)可能主要是制定開發(fā)計劃和任務(wù)分配胚股,并把控進(jìn)度。但若作為一名產(chǎn)品經(jīng)理裙秋,職責(zé)可能就需要額外負(fù)責(zé)需求分析琅拌、產(chǎn)品設(shè)計的工作,職位越高摘刑,責(zé)任越大嘛进宝。

按照之前的設(shè)計,我們就需要針對同一個項目不同的角色分別提供不同的實現(xiàn)枷恕,這顯然是不合理的党晋。且每個角色都被賦予了同樣的流程管理功能,這也是不符合現(xiàn)實場景的徐块。那如何做到項目管理根據(jù)不同角色和不同項目靈活變化呢未玻?要想做到這一點,我們就必須將之前項目管理和項目的緊耦合關(guān)系松松綁胡控。而如何松綁呢扳剿,咱們借助『橋接模式』。

Talk is cheap, show you the code!

代碼:

從面向?qū)ο蟮慕嵌戎缂ぃ覀兛梢猿橄蟪鼋?jīng)理和項目兩個對象庇绽,將這些工作流程抽象為具體的行為方法。

那這些行為方法的附屬該如何設(shè)置呢橙困?經(jīng)理作為項目的主要把控者瞧掺,以上的工作是經(jīng)理的職責(zé)所在。但是凡傅,這些工作又都是基于項目的辟狈,也就是說我們也可以將這些工作看成是項目本身的行為。你可能會按以人為本的思想像捶,將這些行為方法定義到經(jīng)理的角色里上陕。但這樣就會有一個問題,假設(shè)項目經(jīng)理在項目尚未結(jié)束的時候因為某些因素辭職了或人事變動調(diào)離了拓春,那之前的項目的工作安排就不可控了释簿,這是不允許的。所以最好還是把這些行為方法定義到具體的項目中去硼莽。

public abstract class Project
{
    public string ProjectName { get; set; }

    protected Project(string projectName)
    {
        ProjectName = projectName;
    }

    /// <summary>
    /// 需求分析
    /// </summary>
    public abstract void AnalyzeRequirement();

    /// <summary>
    /// 產(chǎn)品設(shè)計
    /// </summary>
    public abstract void DesignProduct();

    /// <summary>
    /// 制定計劃
    /// </summary>
    public abstract void MakePlan();

    /// <summary>
    /// 任務(wù)分解
    /// </summary>
    public abstract void ScheduleTask();

    /// <summary>
    /// 進(jìn)度把控
    /// </summary>
    public abstract void ControlProcess();

    /// <summary>
    /// 產(chǎn)品發(fā)布
    /// </summary>
    public abstract void ReleaseProduct();

    /// <summary>
    /// 后期運(yùn)維
    /// </summary>
    public abstract void MaintainProduct();
}

那如何做到不同的角色賦予不同的項目管理職責(zé)呢庶溶?我們可以將職責(zé)最少的角色抽象出來。比如我們可以將項目經(jīng)理制定產(chǎn)品計劃懂鸵、任務(wù)分配和進(jìn)度把控抽離出來偏螺。

public abstract class Manager
{
    protected Project CurrentProject { get; }

    protected Manager(Project currentProject)
    {
        CurrentProject = currentProject;
    }

    /// <summary>
    /// 制定計劃
    /// </summary>
    public abstract void SchedulePlan();

    /// <summary>
    /// 任務(wù)分配
    /// </summary>
    public abstract void AssignTasks();

    /// <summary>
    /// 進(jìn)度把控
    /// </summary>
    public abstract void ControlProcess();


    /// <summary>
    /// 項目管理
    /// </summary>
    public virtual void ManageProject()
    {
        SchedulePlan();
        AssignTasks();
        ControlProcess();
    }
}

然后項目經(jīng)理和產(chǎn)品經(jīng)理繼承實現(xiàn)基本職責(zé),根據(jù)需要動態(tài)添加額外的職責(zé)匆光。

我們看看項目經(jīng)理的具體實現(xiàn):

/// <summary>
/// 項目經(jīng)理
/// </summary>
public class ProjectManager : Manager
{
    public ProjectManager(Project currentProject) : base(currentProject)
    {
    }

    public override void SchedulePlan()
    {
        base.CurrentProject.MakePlan();
    }

    public override void AssignTasks()
    {
        base.CurrentProject.ScheduleTask();
    }

    public override void ControlProcess()
    {
        base.CurrentProject.ControlProcess();
    }
    public override void ManageProject()
    {
        Console.WriteLine($"項目經(jīng)理負(fù)責(zé)【{base.CurrentProject.ProjectName}】:");
        base.ManageProject();
    }

}

再看看產(chǎn)品經(jīng)理的實現(xiàn):

/// <summary>
/// 產(chǎn)品經(jīng)理
/// </summary>
public class ProductManger : Manager
{
    public ProductManger(Project currentProject) : base(currentProject)
    {
    }
    public override void SchedulePlan()
    {
        base.CurrentProject.MakePlan();
    }

    public override void AssignTasks()
    {
        base.CurrentProject.ScheduleTask();
    }

    public override void ControlProcess()
    {
        base.CurrentProject.ControlProcess();
    }
    public void AnalyseRequirement()
    {
        base.CurrentProject.AnalyzeRequirement();
    }

    public void DesignProduct()
    {
        base.CurrentProject.DesignProduct();
    }

    public override void ManageProject()
    {
        AnalyseRequirement();
        DesignProduct();
        base.ManageProject();
    }

    public override void ManageProject()
    {
        Console.WriteLine($"產(chǎn)品經(jīng)理負(fù)責(zé)【{base.CurrentProject.ProjectName}】:");
        AnalyseRequirement();
        DesignProduct();
        base.ManageProject();
    }

}

可以看到我們?yōu)楫a(chǎn)品經(jīng)理額外添加了需求分析和產(chǎn)品設(shè)計的職責(zé)套像。

最終類圖

下面我們看看最終的場景類:

Project webProject = new WebProject("Web項目");
Manager projectManager = new ProjectManager(webProject);
Manager productManager = new ProductManger(webProject);

projectManager.ManageProject();
productManager.ManageProject();

Console.ReadLine();
運(yùn)行結(jié)果

總結(jié):

通過上面的demo,我們解決了之前通過繼承設(shè)計的弊端终息,即項目管理和項目不能靈活適應(yīng)變化夺巩。通過引入橋接模式,將項目管理和項目解耦周崭,我們實現(xiàn)了項目管理(抽象)和項目(實現(xiàn))的分離柳譬。橋接模式的意圖還是對變化的封裝,盡量把可能變化的因素封裝到最細(xì)续镇、最小的邏輯單元中美澳,避免風(fēng)險擴(kuò)散。而這也正是橋接模式的精髓所在摸航。

優(yōu)缺點:

橋接模式將抽象和實現(xiàn)分離制跟,實現(xiàn)可以不受抽象的約束,不用再綁定在一個固定的抽象層次上酱虎;抽象和實現(xiàn)均可自由擴(kuò)展凫岖。

應(yīng)用場景:

  1. 不希望或不適用使用繼承的場景
  2. 接口或抽象類不穩(wěn)定的場景
  3. 重用性要求較高的場景
  4. 解決多層繼承

實際案例:

數(shù)據(jù)庫:Orace、SQL Server
數(shù)據(jù)庫訪問技術(shù):NHibernate逢净、EntityFramework
每種數(shù)據(jù)庫都可以用不同的數(shù)據(jù)庫訪問技術(shù)汪拥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末右蕊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贬堵,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件载碌,死亡現(xiàn)場離奇詭異胁后,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)琼娘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門峭弟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來附鸽,“玉大人,你說我怎么就攤上這事瞒瘸】辣福” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵情臭,是天一觀的道長省撑。 經(jīng)常有香客問我,道長俯在,這世上最難降的妖魔是什么竟秫? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮跷乐,結(jié)果婚禮上肥败,老公的妹妹穿的比我還像新娘。我一直安慰自己愕提,他們只是感情好拙吉,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揪荣,像睡著了一般筷黔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仗颈,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天佛舱,我揣著相機(jī)與錄音,去河邊找鬼挨决。 笑死请祖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脖祈。 我是一名探鬼主播肆捕,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盖高!你這毒婦竟也來了慎陵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤喻奥,失蹤者是張志新(化名)和其女友劉穎席纽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撞蚕,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡润梯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纺铭。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡寇钉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舶赔,到底是詐尸還是另有隱情扫倡,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布顿痪,位于F島的核電站镊辕,受9級特大地震影響油够,放射性物質(zhì)發(fā)生泄漏蚁袭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一石咬、第九天 我趴在偏房一處隱蔽的房頂上張望揩悄。 院中可真熱鬧,春花似錦鬼悠、人聲如沸删性。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹬挺。三九已至,卻和暖如春它掂,著一層夾襖步出監(jiān)牢的瞬間巴帮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工虐秋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留榕茧,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓客给,卻偏偏與公主長得像用押,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子靶剑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容