1.“单一职责”模式
软件组件设计中,如果责任划分不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。
典型模式:
Decorator
Bridge
2.桥接模式的动机(Motivation)
利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外地复杂度?
合成/聚合复用原则,即优先使用对象合成/聚合,而不是类继承,有助于保持每个类并封装,并集中在单个任务上
3.问题的引入
手机都有通讯录和游戏功能,M品牌手机和N品牌都有通讯录的增删改查功能和游戏功能。
结构1: 父类是’手机品牌‘,下有’手机品牌M‘和‘手机品牌N’,每个子类下各有‘通讯录’和‘游戏’子类。
结构2:父类是‘手机软件’,下有‘通讯录’和‘游戏’子类,每个子类下各有‘手机品牌M’和‘手机品牌N’.
这两种结构在增加手机品牌或手机软件时都会非常麻烦。
使用合成/聚合复用原则,用对象的职责来考虑问题。
本质上,’游戏‘,’通信录‘,’音乐播放器‘这些功能都是软件,让其分离与手机的耦合。
品牌和软件之间的继承关系变为聚合关系
//手机软件
abstract class HandsetSoft
{
public abstract void Run();
}
//手机品牌
abstract class HandsetBrand
{
protected HandsetSoft soft;
//设置手机软件
public void SetHandsetSoft(HandsetSoft soft)
{
this.soft=soft;
}
//运行
public abstract void Run();
}
//手机品牌M
class HandsetBrandM extends HandsetBrand
{
public void Run(){
System.out.println("M Brand");
soft.Run();
}
}
//手机品牌N
class HandsetBrandN extends HandsetBrand
{
public void Run(){
System.out.println("N Brand");
soft.Run();
}
}
//手机游戏
class HandsetGrame extends HandsetSoft{
public void Run()
{ System.out.println("运行手机游戏"); }
}
//手机通讯录
class AddressList extends HandsetSoft{
public void Run()
{ System.out.println("运行手机通讯录"); }
}
//手机mp3
class Mp3 extends HandsetSoft{
public void Run()
{ System.out.println("运行手机mp3"); }
}
//客户端
public class CellPhonePattern{
public static void main(String[] args){
HandsetBrand ab;
ab=new HandsetBrandN();
ab.SetHandsetSofy(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();
}
}
如果要增加软件
只需要增加一个新的软件类(继承抽象软件类)即可,不会影响其他类
增加手机品牌,扩展手机品牌即可,继承手机品牌抽象类。客户端,增加。ab=new HandsetBrandS(); 然后设置需要的软件即可。
4.本质
分离抽象和实现