牵线搭桥,『桥接模式』

目录:设计模式之小试牛刀
源码路径:Github-Design Pattern


定义:(Bridge Pattern)

将抽象和实现解耦,使得两者可以独立地变化。

类图:

桥接模式通用类图

启示:

一个产品的研发,流程主要包括需求分析、产品设计、制定计划、任务安排、进度把控、产品发布、后期运维。

按照我们一般的设计思路,我们可能会如下设计:

一般的设计思路

定义一个抽象的ProjectManager类,用来定义项目的开发流程,不同的项目通过继承来实现具体的流程。每增加新的项目,就只需要继承该类重新实现即可。但这仅适用于某个单一角色对产品的管理。

我们知道一个IT公司的组织架构一般由CEO、产品经理、项目经理和员工组成。CEO负责整个公司运行项目的整体把控,产品经理负责公司的某一条产品线,项目经理则负责产品线中的某个项目的开发管理,而员工就是负责项目的开发工作。

作为一名项目经理,职责可能主要是制定开发计划和任务分配,并把控进度。但若作为一名产品经理,职责可能就需要额外负责需求分析、产品设计的工作,职位越高,责任越大嘛。

按照之前的设计,我们就需要针对同一个项目不同的角色分别提供不同的实现,这显然是不合理的。且每个角色都被赋予了同样的流程管理功能,这也是不符合现实场景的。那如何做到项目管理根据不同角色和不同项目灵活变化呢?要想做到这一点,我们就必须将之前项目管理和项目的紧耦合关系松松绑。而如何松绑呢,咱们借助『桥接模式』。

Talk is cheap, show you the code!

代码:

从面向对象的角度,我们可以抽象出经理和项目两个对象,将这些工作流程抽象为具体的行为方法。

那这些行为方法的附属该如何设置呢?经理作为项目的主要把控者,以上的工作是经理的职责所在。但是,这些工作又都是基于项目的,也就是说我们也可以将这些工作看成是项目本身的行为。你可能会按以人为本的思想,将这些行为方法定义到经理的角色里。但这样就会有一个问题,假设项目经理在项目尚未结束的时候因为某些因素辞职了或人事变动调离了,那之前的项目的工作安排就不可控了,这是不允许的。所以最好还是把这些行为方法定义到具体的项目中去。

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

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

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

    /// <summary>
    /// 产品设计
    /// </summary>
    public abstract void DesignProduct();

    /// <summary>
    /// 制定计划
    /// </summary>
    public abstract void MakePlan();

    /// <summary>
    /// 任务分解
    /// </summary>
    public abstract void ScheduleTask();

    /// <summary>
    /// 进度把控
    /// </summary>
    public abstract void ControlProcess();

    /// <summary>
    /// 产品发布
    /// </summary>
    public abstract void ReleaseProduct();

    /// <summary>
    /// 后期运维
    /// </summary>
    public abstract void MaintainProduct();
}

那如何做到不同的角色赋予不同的项目管理职责呢?我们可以将职责最少的角色抽象出来。比如我们可以将项目经理制定产品计划、任务分配和进度把控抽离出来。

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

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

    /// <summary>
    /// 制定计划
    /// </summary>
    public abstract void SchedulePlan();

    /// <summary>
    /// 任务分配
    /// </summary>
    public abstract void AssignTasks();

    /// <summary>
    /// 进度把控
    /// </summary>
    public abstract void ControlProcess();


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

然后项目经理和产品经理继承实现基本职责,根据需要动态添加额外的职责。

我们看看项目经理的具体实现:

/// <summary>
/// 项目经理
/// </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($"项目经理负责【{base.CurrentProject.ProjectName}】:");
        base.ManageProject();
    }

}

再看看产品经理的实现:

/// <summary>
/// 产品经理
/// </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($"产品经理负责【{base.CurrentProject.ProjectName}】:");
        AnalyseRequirement();
        DesignProduct();
        base.ManageProject();
    }

}

可以看到我们为产品经理额外添加了需求分析和产品设计的职责。

最终类图

下面我们看看最终的场景类:

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

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

Console.ReadLine();
运行结果

总结:

通过上面的demo,我们解决了之前通过继承设计的弊端,即项目管理和项目不能灵活适应变化。通过引入桥接模式,将项目管理和项目解耦,我们实现了项目管理(抽象)和项目(实现)的分离。桥接模式的意图还是对变化的封装,尽量把可能变化的因素封装到最细、最小的逻辑单元中,避免风险扩散。而这也正是桥接模式的精髓所在。

优缺点:

桥接模式将抽象和实现分离,实现可以不受抽象的约束,不用再绑定在一个固定的抽象层次上;抽象和实现均可自由扩展。

应用场景:

  1. 不希望或不适用使用继承的场景
  2. 接口或抽象类不稳定的场景
  3. 重用性要求较高的场景
  4. 解决多层继承

实际案例:

数据库:Orace、SQL Server
数据库访问技术:NHibernate、EntityFramework
每种数据库都可以用不同的数据库访问技术。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容