设计模式——桥接(Bridge)

在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类持续膨胀,同时充斥着重复代码,这时候的关键是划清责任。

  • Decorator
  • Bridgd
    手机都有通讯录和游戏功能,M品牌手机和N品牌手机都有通讯录的增删改查功能和游戏功能。可以有两种结构:
    一、
    父类是手机品牌,下有手机品牌M和手机品牌N,每个子类下各有通讯录和游戏子类。
    在这里插入图片描述

二、
父类是手机软件,下有通讯录和游戏软件,每个子类下各有手机品牌M和手机品牌N.

在这里插入图片描述
在面向对象中有一个很重要的设计原则:
合成、聚合复用原则。即优先使用对象合成、聚合,而不是类继承。
优点:优先使用对象的合成、聚合有利于保持每个类并封装,并集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
实际上,上面的例子,需要用对象的职责,而不是结构来考虑问题。
游戏、通讯录这些功能都是软件,让其分离与手机的耦合,就大大减少面对新需求时改动过大的不合理情况。
应该有个手机品牌和手机软件抽象类,让不同的品牌和功能都分别继承他们,这样需要增加新的类或新的功能就不会影响其他的类了。
下面是实现代码:

//手机软件
abstract class HandSetSoft
{
  public abstract void Run();
} 
abstract class HandSetBrand
{
   protected HandSetSoft;//设置手机软件
   public void SetHandSetSoft(HandSetSoft soft)
   {
      this.soft=soft;
   }
   public abstract void Run();
}
class HandSetBrandM extends HandSetBrand //手机品牌M
{
  public void run()
  {
  System.out.println("M Brand");
  soft.Run();
} 
class HandSetBrandN extends HandSetBrand //手机品牌N
{
  public void run()
  {
  System.out.println("N Brand");
  soft.Run();
} 
class HandSetGame extends HandSetSoft
{
      public void Run()
      {
       System.out.println("运行手机游戏");
      }
}
class Address extends HandSetSoft
{
      public void Run()
      {
       System.out.println("运行通讯录");
      }
}
class HandSetMp3 extends HandSetSoft
{
      public void Run()
      {
       System.out.println("运行手机Mp3");
      }
}
public class CellPhonePatten
{
    public static void main(String [] args)
    {
       HandSetBrand ab;
       ab=new HandSetBrandN();
       ab.SetHandSetSoft( new HandSetGame());
       ab.Run();
       ab.SetHandSetSoft(new AddressList());
       ab.Run();
       ab=new HandSetBrandM();
       ab.SetHandSetSoft( new HandSetGame());
       ab.Run();
       ab.SetHandSetSoft(new AddressList());
       ab.Run();
       ab.SetHandSetSoft(new Mp3());
       ab.Run();
       
    }
}

如果现在我们想要增加一个功能,比如拍照功能,在手机软件部分增加手机拍照子类。类的个数增加也只是一个。不影响其他任何类。
同样的想要增加一个品牌,操作类似。
这样的设计符合开放——封闭原则,不会修改原来的代码,而只是扩展类就可以了。
合成/聚合原则,优先使用对象的合成或聚合,而不是类继承。
因为继承很容易造成不必要的麻烦,其本质原因是;
继承是一种强耦合的结构,父类变,子类就必须要交,所以在使用继承时,一定要在是‘is -a’的关系即一对一在考虑使用。

桥接模式

在这里插入图片描述

可以看出,这个系统含有两个等级结构:

  • 由抽象化角色和提炼抽象化角色组成的抽象化等级结构。
  • 由实现化角色和两个具体实现化角色所组成的实现化等级结构。
    实现代码:
//Imlementor
abstract class Implementor
{
    public abstract void Operation();
}
public class ConcreteImplementorA extends Implementor
{
    public void Operation()
    {
      System.out.println("具体实现A的方式执行");
    }
}
public class ConcreteImplementorB extends Implementor
{
    public void Operation()
    {
      System.out.println("具体实现B的方式执行");
    }
}
public class Abstraction
{
    protected Implementor implementor;
    public void SetImplementor(Implementor implementor)
    { 
      this.implementor=implementor;
    }
    public void Operation()
    {
      implementor.Operation();
    }
}
public class RefinedAbstraction extends Abstraction
{
   public void Operation()
   { 
       implementor.Operation();
   }
} 
public class client
{
   public static void main(String []args)
   {
      Abstraction ab=new RefinedAbstraction();
      ab.SetImplementor(new ConcreteImplementorA());
      ab.Operation();
      ab.SetImplementor(new ConcreteImplementorB());
      ab.Operation();
   }
}

桥接模式

就是将抽象部分与他的实现部分分离,其实就是实现系统可能有多角度分类,让每一种分类都可能变化,那么就把这种多角度分离出来让他们独立变化,减少他们之间的耦合。
在桥接模式中的桥接是单向的,也就是只能是抽象部分的对象去使用具体实现部分的对象,而不能反过来,也就是单向桥。
使用桥接和原始模式的根本区别在于是通过继承还是通过合成/聚合的方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:Favor Composition Over Inheritance
**

本质

就是分离抽象与实现

**

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值