初识设计模式 chapter 01-入门
1.引言
上周快速地把《Head First设计模式》推到第7章,这周状态不佳,除了写了个工具之外书都没翻,现在连设计模式的名字都记不全了,深感大脑记忆学的快忘的也快。本着好记性不如烂笔头的原则,同时也方便以后自己再来复习回顾的时候不用大篇地再把原书翻一遍,以后每一章都会写一篇博客用来自我总结。
2.正文笔记
2.1继承的缺点
1、代码在多个子类中重复,因为
所有子类需要覆盖父类的抽象方法;
2、子类运行时不容易改变状态,因为没有setter方法;
3、很难知道所有子类的全部行为;
4、改变牵一发而动全身,造成其他子类不想要的改变。
2.2在软件开发商,有什么是你可以深信不疑的?
需求变更,change!
2.3设计原则
找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
把会变化的部分取出并“封装”起来,好让其他部分不会受到影响。
针对接口编程,而不是针对实现编程。
父类为抽象类,方法为接口,接口与实现分离。
多用组合(一个接口多个实现类),少用集成。
2.4 最终的抽象duck父类
public abstract class duck
{
FlyBehavior flybehavior;
QuackBehavior quackbehavior;
public duck()
{
}
public void abstract display();
public void performFly()
{
flybehavior.fly();
}
public void performQuack()
{
quackbehavior.quack();
}
public void swim()
{
System.out.println("All ducks float, even decoys.");
}
}
从上述定义类中可以总结出的设计经验有:
1、父类设计为抽象类,其中的抽象方法必须被子类实现;
2、父类中有三种方法:抽象方法、父类已定义的方法(swim)、实现可变的方法(performFly和performQuack);
3、纯粹的继承只是为了引入多态,何为纯粹,就是只包含抽象方法和父类已定义的方法,如果performFly和performQuack也定义为抽象方法则会造成子类的代码冗余;
4、这里针对接口编程的目的非常明显,duck拥有不同的fly和quack方式,分别用两个接口来定义,再分别通过一组实现类来定义具体的实现方式,子类集成duck类时只要选择具体的某一个实现类即可,且即使发生需求变更,也只需要修改特定的实现类,而不用修改所有子类定义。
复习一下抽象的几个概念:
1、抽象方法abstract,父类的抽象方法主要作用为占位,由子类来实现;
2、为了提高清晰度,包含一个或多个抽象方法的类本身必须声明为抽象类;
3、类即使不包含抽象方法,也可以声明为抽象类;
4、抽象类不能被实例化。
2.5动态设定行为
public void setFlyBehavior(FlyBehavior fb)
{
flybehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb)
{
quackbehavior = qb;
}
加上setter方法后,就可以动态的改变子类的具体行为。
2.6策略模式定义
策略模式,定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式也可以把你的思考架构的层次提高到模式层面,而不是仅停留在琐碎的对象上。
比如购物网站的结算模式,对于不同的级别的客户折扣不一样,这时候就可以对结算使用组合方法,定义为一个接口和多个实现。
3本章结语
我们全都使用别人设计好的库与框架。我们讨论库与框架、利用他们的API编译成我们的程序、享受运用别人的代码所带来的优点。看看java api它所带来的功能:网络、GUI、IO等。库与框架长久以来,一直扮演着软件开发过程的重要角色,我们从中挑选所要的组件,把他们放进合适的地方。但是,库与框架无法帮助我们将应用组织成容易了解、容易维护、具有弹性的架构,所以要设计模式。
设计模式不会直接进入你的代码中,而是先进入你的“大脑”中。一旦你先在脑海中装入了许多关于模式的知识,就能够开始新设计中采用它们,并当你的旧代码变得如同搅和成一团没有弹性的意大利面一样时,可以用它们重做旧代码。