举个我们最常用的Photoshop做例子。
在Photoshop中,有许多图形工具,比如星星,比如方形,再比如圆形等等。
在Photoshop中,不用多说,也有很多种颜色供我们选择。
于是就产生了,红色的星星,绿色的星星。红色的方形,绿色的方形等等。
看看所产生的树:
现在是三种图形,三种颜色,于是我们就一共去声明了九个类,当然我们还不算中间过程中的辅助父类。
如果我们现在是18种图形,12种颜色,那么我们就需要写18*12个类,然后加上12个颜色的类和一个总父类,一共我们需要12*18+12+1=229个类。
采用多继承
用多继承描述这个模型再恰当不过了。声明18个图形的类,然后声明12个颜色的类,然后用具体的图形类去多继承。
让我们看看这个表述图:
错综复杂的线看上去可能有些乱,但是我想大家应该都明白这个意思。
理解倒是容易理解了,可是这个时候我们再来看一下这个类的数量:
颜色12+颜色父类1+图形18+图形父类1+12*18,这个数字似乎比我们之前的那个数字还要大。
也许我会为他辩驳说他牺牲了空间而换取了可读性,
桥接模式
这个时候让我们来计算一下类的总数:
12个颜色类+18个图形类+1个我们的图形=31个类
class IColor { }
class RedColor : IColor { }
class BlueColor : IColor { }
class YellowColor : IColor { }
class IGraphics { }
class Rectangle:IGraphics { }
class Star:IGraphics { }
class Round : IGraphics { }
class PhotoShop
{
IColor color;
IGraphics graphics;
public PhotoShop(IColor c, IGraphics g)
{
this.color = c;
this.graphics = g;
}
public void Draw()
{
cout << color.GetType() <<endl;
cout << graphics.GetType() <<endl;
}
}
桥接模式(Bridge pattrern):将抽象部分与实现部分向分离,使他们都可以独立变化。
引深:
1.接口是行为的契约,而抽象类是特征的抽象。一个是can do,一个是is a。
2.面向对象设计原则说:组合优于继承。
上面的代码,如果不仅仅要求颜色和形状,还要求更多,那么我就要写很多很多的属性,好麻烦。
而且更重要的是,如果有这样的需求,我现在有12种颜色,然后有3种形状,分别是方形,圆形和星星,有两种笔,分别是铅笔和蜡笔。但是我现在铅笔只对应方形和星星,蜡笔只对应圆形和星星。也就是说不存在圆形铅笔和方形蜡笔。这样的话我的组合不是浪费了么?而且客户很可能组合错呀?
是的,不要一味去考虑组合。再重复一次我很爱说的话:模式是为了变化,不要为了模式而模式,我们只需要抽离出变化点就可以了!
如果这样,那我们就写好稳定的部门