`

Head First Design Patterns

阅读更多

1. 设计原则
    封装变化

    针对接口编程,不要针对实现编程

    多用组合,少用继承

    为了交互对象之间的松耦合设计而努力

    类应该对扩展开放,对修改关闭

    要依赖抽象,不要依赖具体类 - 依赖倒置原则(Dependency Inversion Principle)

    只和朋友交谈

    别找我,我会找你

    类只有一个改变的理由

 

 

2. 策略模式(Strategy)

    定义了算法族,分别封装起来,让它们之间可以相互替换,让算法的变化独立于使用算法的客户 - 鸭子模拟器

 

 

3. 观察者模式(Observer)

    定义了对象之间的一对多依赖,当一个对象状态改变时,所有的依赖者都会收到通知并自动更新 - 气象观测站
    观察者模式(Observer) = 出版者(Subject) + 订阅者(Observer)

   

    Java内置了观察者模式,java.util.Observer(同Observer)和java.util.Observable(同Subject)。
    3.1 如何定义观察者对象
    实现java.util.Observer接口,调用Observable.addObserver()添加观察者,调用Observable.deleteObserver

    ()删除观察者
    3.2 如何发通知
    应用扩展Observable接口,然后调用setChanged()方法标记状态改变,接着调用两种notifyObservers()或

    notifyObservers(Object arg)中一个
    3.3 观察者如何接受通知
    观察者的update(Observable o, Object arg)方法
    如果推(push)数据给观察者,那么调用notifyObservers(Object arg)方法
    如果观察者主动拉(pull),那么主题类中,先调用setChanged(),然后调用notifyObservers(),同时把所有参数给

    出getXXX方法,以便观察者获取

//主题接口 - 对象使用此接口注册,删除,通知
interface Subject {
    registerObserver()
    removeObserver()
    motifyObservers()
}

//观察者接口 - 只有一个update()方法,主题状态改变时被调用
interface Observer {
    update()
}

//具体主题 - 实现注册,删除,通知,同时能获取和设置状态
ConcreteSubject implements Subject {
    registerObserver() {...}
    removeObserver(){...}
    motifyObservers(){...}
    getState()
    setState()
}

//具体观察者 - 必须注册具体主题
ConcreteObserver implements Observer {
    update()
}

 

 

4. 装饰器模式(Decorator)

    动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案 - 星巴兹咖啡
    Java I/O是典型的装饰器模式

//Component - 抽象组件
Component {
    methodA()
    methodB()
}

//ConcreteComponent - 具体组件
ConcreteComponent extends Component {
    methodA()
    methodB()
}

//Decorator - 装饰者共同接口
Decorator extends Component {
    methodA()
    methodB()
}

//ConcreteDecoratorA
ConcreteDecoratorA extends Decorator {
    Component wrappedObj  //可以记录装饰的对象
    methodA()
    methodB()
    newBehavior()
}

//ConcreteDecoratorB
ConcreteDecoratorB extends Decorator {
    Component wrappedObj  //可以记录装饰的对象
    Object newState  //装饰者可以扩展Component状态
    methodA()
    methodB()
}

 

 

5. 工厂方法模式(Facotory Methods)

    定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类 - 比萨店
    简单工厂(Simple Factory): 一个工厂类,一个抽象产品类,一系列具体产品类
    工厂方法(Factory Method): 一个抽象工厂类,一系列具体工厂类,一个抽象产品类,一系列具体产品类
    抽象工厂(Simple Factory): 提供一个接口,用于创建相关或依赖对象的家族,而不需要指明具体类。注意,是创建

    一个家族,说明里面产品很多啊
    抽象工厂的每个方法看起来都像工厂方法,所以抽象工厂定义一组创建产品的接口,由工厂方法来实现

 

 

6. 单例模式(Singleton)

    确保一个类只有一个实例,并提供全局访问点 - 巧克力工厂

 

 

7. 命令模式(Command)

    将"请求"封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,同时支持撤销操作 - 神奇遥控器

 

    Client: 客户端需要创建一个ConcreteCommand,同时设置Receiver
    Invoker: 调用者持有命令对象,执行execute()方法
    Command: 接口
    ConcreteCommand: 具体执行者,会调用Receiver方法
    Receiver: 进行必要的工作

    能够进行Undo操作,在具体命令中记录先前状态,然后添加相应方法,重新设置到原来的状态
    宏命令: 就是把一堆具体命令,放在一个方法中执行
    还可以把命令模式用于队列请求,一个线程从队列中取出任务,然后执行execute()
    日志请求: 每个命令执行时,可以存储状态到磁盘,如果Down之后,可以恢复

 

 

8. 适配器模式(Adapter)

    将一个类的接口,转换成客户期望的另一个接口,让原本接口不兼容的类可以合作无间 - 鸭子和火鸡
    适配器只是转换不同的接口,而装饰器可能会加入新的方法

 

 

9. 外观模式(Facade)

    提供一个统一的接口,来访问子系统中的一群接口 - 家庭影院
    比如要执行一系列操作,那么使用外观模式,把所有操作封装起来,给客户端一个方法调用即可

 

 

10. 模板方法(Template)

    在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中 - 咖啡和茶的制作方法
    可以自己实现一部分方法,另外一些方法在子类实现,那么就在父类定义抽象方法,让子类执行

//抽象类
abstract class AbstractClass {
    //声明为final,以免子类改变该算法
    final void templateMethdo() {
        primitiveOperation1();
        primitiveOperation2();
        concreteOperation();
        hook(); 
    }
    //定义两个原语操作,由子类实现
    abstract void primitiveOperation1();
    abstract void primitiveOperation2();
    
    void concreteOperation() {
    }
    
    void hook() {}  //子类来决定需不需要做事
}

 

 

11. 好莱坞原则

    抽象组件决定什么时候使用低层组件,而不让低层组件依赖抽象组件

    策略和模板都封装算法,策略用组合,而模板使用继承

 

 

12. 迭代器(Iterator)

    提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部的表示。

 

 

13. 组合(Composite)

    允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象和对象组合。
    对象村多种类型菜单

 

 

14. 状态模式(State)

    允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类 - 万能糖果销售机

 

 

15. 代理模式(Proxy)

    为另一个对象提供一个替身或占位符以控制对这个对象的访问
    远程代理: 可以作为一个JVM对象的本地代表,调用代理方法,可以执行远程对象方法。譬如远端监控万能糖果机
    虚拟代理: 创建开销大的对象代表。譬如CD浏览器,启用另外一个线程,从网络上下载CD封面
    动态代理: java.lang.reflect,运行时动态创建代理类,实现一个多个接口,将方法的调用转发到你指定的类
    保护代理: 让有权限的用户进行访问

 

 

16. 复合模式(Compound)

    结合两个或以上的模式,组成一个解决方案,解决已在发生的一般性问题。
    MVC结合了观察者模式,策略模式,组合模式

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics