常见设计模式要点总结

前言

最近在看《head first 设计模式》,发现每一个章节后的要点总结都是言简意骇,因此特写此篇博客对常见的设计模式要点作个总结。
<!-- more -->前端

观察者模式

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新java


  • 观察者模式定义了对象之间一对多的关系
  • 主题(可观察者)用一个共同对接口来更新观察者
  • 被观察者不知道观察者的细节,只知道观察者实现了观察者接口
  • 多个观察者时,不能够依赖特定的通知顺序

 ●  抽象主题(Subject)角色:抽象主题角色把全部对观察者对象的引用保存在一个汇集(好比ArrayList对象)里,每一个主题均可以有任何数量的观察者。抽象主题提供一个接口,能够增长和删除观察者对象,抽象主题角色又叫作抽象被观察者(Observable)角色。设计模式

  ●  具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给全部登记过的观察者发出通知。具体主题角色又叫作具体被观察者(Concrete Observable)角色。多线程

  ●  抽象观察者(Observer)角色:为全部的具体观察者定义一个接口,在获得主题的通知时更新本身,这个接口叫作更新接口。并发

  ●  具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使自己的状态与主题的状态 像协调。若是须要,具体观察者角色能够保持一个指向具体主题对象的引用。学习

装饰者模式

动态的将责任加到对象上,想要扩展功能,装饰者提供有别于继承的另外一种选择spa


  • 装饰者模式意味着一群装饰者类,这些类用来包装具体组件
  • 装饰者类都通过接口或继承实现
  • 能够用无数个装饰者包装一个组件
  • 装饰者会致使设计中出现许多小对象,过分使用会让程序复杂

在装饰模式中的角色有:线程

  ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。设计

  ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。代理

  ●  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

  ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

工厂模式

简单工厂:定义了一个建立对象的接口,但由子类决定要实例化的类是哪个。

抽象工厂:提供一个接口,用于建立相关或依赖对象的家族而不须要明确指定具体的类


  • 全部的工厂都是用来封装对象的建立
  • 工厂方法使用继承:把对象的建立委托给子类,子类实现工厂方法来建立对象
  • 抽象工厂使用对象组合:对象的建立被实如今工厂接口所暴露出来的方法中
  • 抽象工厂建立相关的对象家族,不须要依赖他们的具体类
  • 依赖倒置原则,依赖于抽象而非具体类型

下图是简单工厂模式的uml图

简单工厂的关注点是产品,如上图中的CpuFactory,MainboardFactory。当咱们须要新增一个产品的时候(例如memory 就不须要对原有代码进行修改),可是当咱们须要新增一种cpu的时候(例如huawei cpu)简单工厂就须要对原有代码改动了,因而咱们引入第二种抽象工厂。

抽象工厂的关注点是产品族,如上图中的IntelFactory,AmdFactory。当咱们须要新增一个产品族的时候(例如HuaweiFactory 就不须要对原有代码进行修改),可是当咱们须要新增一种产品的时候(例如memory)抽象工厂就须要对原有代码改动了。

以上两种工厂模式,各有优劣。

单例模式

确保一个类只有一个实例并提供全局访问点


  • 单例模式确保程序中一个类最多只有一个实现
  • 单例模式提供访问者合格实例对全局访问点
  • Java中实现单例模式须要私有构造器, 一个静态方法和一个静态变量
  • 必须假设全部的程序都是多线程的,考虑并发的问题
  • 若是使用多个类加载器,可能致使单例模式失效产生多个实例

推荐一种单例模式的最佳实践

public class SingleTon {
    private SingleTon(){}
    
    private static class InstanceHolder{
        private final static SingleTon singleTon = new SingleTon();
    }
    
    public SingleTon getSingleTon(){
        return InstanceHolder.singleTon;
    }
}

适配器模式/门面模式

适配器模式:将一个类的接口转换成指望的另外一个接口,适配器让本来不兼容的类能够合做无间

门面模式:提供了一个统一的接口用来访问子系统的一群接口。外观定义了一个高层接口使得子系统更加易用


  • 当须要使用一个现有的类而其接口并不符合你的须要时,使用适配器
  • 适配器将一个对象包装起来以改变其接口,装饰者将一个对象包装起来以增长新的行为和责任,门面模式将一群对象“包装”简化其接口
  • 当须要简化并赞成一个很大的接口或者一群复杂的接口时使用门面模式
  • 门面模式能够从一个复杂的子系统中解耦
  • 使用一个门面模式须要将子系统组合进外观中,而后将工做委托给子系统执行

适配器uml图

模式所涉及的角色有:

  ●  目标(Target)角色:这就是所期待获得的接口。注意:因为这里讨论的是类适配器模式,所以目标不能够是类。

  ●  源(Adapee)角色:如今须要适配的接口。

  ●  适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不能够是接口,而必须是具体类

门面模式相对比较简单

上图是我暑假在阿里实习作的一个小需求。其中核身组件就用到了门面模式,将核身组件这个领域对象暴露给前端,使得前端没必要关注具体的每一个核身项,从一个复杂的子系统中解耦。

代理模式

一个替身或占位符以访问这个对象


  • 代理模式为另外一个对象提供表明,以便控制客户对对象的访问
  • 代理在结构上相似装饰者但目的不一样
  • 装饰者模式为对象加上行为,而代理则是控制访问

在代理模式中的角色:

  ●  抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可使用目标对象的地方均可以使用代理对象。

  ●  目标对象角色:定义了代理对象所表明的目标对象。

  ●  代理对象角色:代理对象内部含有目标对象的引用,从而能够在任什么时候候操做目标对象;代理对象提供一个与目标对象相同的接口,以即可以在任什么时候候替代目标对象。代理对象一般在客户端调用传递给目标对象以前或以后,执行某个操做,而不是单纯地将调用传递给目标对象。

总结

想要学习设计模式的初衷是,如何写出更灵活,更健壮,更符合规范的代码。也确实从设计模式的学习中感觉到了面向对象的强大,不过纸上得来终觉浅,绝知此事要躬行。

参考文档:

《Head First 设计模式》

相关文章
相关标签/搜索