《设计模式之禅》读书笔记


  • 创建类模式 
    • 工厂方法模式http://blog.csdn.net/jason0539/article/details/23020989
      • 意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
      • 适用性:当一个类不知道它所必须创建的对象的类的时候;当一个类希望由它的子类来指定它所创建的对象的时候;当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
      • 工厂模式的最终目的都是解耦
      • 宝马车的例子
      • 工厂方法模式组成:
      •   1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
      •   2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
      •   3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
      •   4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
      • 产品类:

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. abstract class BMW {  
        2.     public BMW(){  
        3.           
        4.     }  
        5. }  
        6. public class BMW320 extends BMW {  
        7.     public BMW320() {  
        8.         System.out.println("制造-->BMW320");  
        9.     }  
        10. }  
        11. public class BMW523 extends BMW{  
        12.     public BMW523(){  
        13.         System.out.println("制造-->BMW523");  
        14.     }  
        15. }  
      • 创建工厂类:

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. interface FactoryBMW {  
        2.     BMW createBMW();  
        3. }  
        4.   
        5. public class FactoryBMW320 implements FactoryBMW{  
        6.   
        7.     @Override  
        8.     public BMW320 createBMW() {  
        9.   
        10.         return new BMW320();  
        11.     }  
        12.   
        13. }  
        14. public class FactoryBMW523 implements FactoryBMW {  
        15.     @Override  
        16.     public BMW523 createBMW() {  
        17.   
        18.         return new BMW523();  
        19.     }  
        20. }  
    • 抽象工厂模式http://blog.csdn.net/jason0539/article/details/44976775
      • 意图:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。
      • 适用性:一个系统要独立于它的产品的创建、组合和表示时;一个系统要由多个产品系列中的一个来配置时;当你要强调一系列相关的产品对象的设计以便进行联合使用时;当你提供一个产品类库,而只想显示它们的接口而不是实现时。
      • 抽象工厂模式的起源或者最早的应用,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同
      • 抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。
      •  产品类: 

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. //发动机以及型号    
        2. public interface Engine {    
        3.   
        4. }    
        5. public class EngineA extends Engine{    
        6.     public EngineA(){    
        7.         System.out.println("制造-->EngineA");    
        8.     }    
        9. }    
        10. public class EngineBextends Engine{    
        11.     public EngineB(){    
        12.         System.out.println("制造-->EngineB");    
        13.     }    
        14. }    
        15.   
        16. //空调以及型号    
        17. public interface Aircondition {    
        18.   
        19. }    
        20. public class AirconditionA extends Aircondition{    
        21.     public AirconditionA(){    
        22.         System.out.println("制造-->AirconditionA");    
        23.     }    
        24. }    
        25. public class AirconditionB extends Aircondition{    
        26.     public AirconditionB(){    
        27.         System.out.println("制造-->AirconditionB");    
        28.     }    
        29. }   
      • 创建工厂类:

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. //创建工厂的接口    
        2. public interface AbstractFactory {    
        3.     //制造发动机  
        4.     public Engine createEngine();  
        5.     //制造空调   
        6.     public Aircondition createAircondition();   
        7. }    
        8.   
        9.   
        10. //为宝马320系列生产配件    
        11. public class FactoryBMW320 implements AbstractFactory{    
        12.         
        13.     @Override    
        14.     public Engine createEngine() {      
        15.         return new EngineA();    
        16.     }    
        17.     @Override    
        18.     public Aircondition createAircondition() {    
        19.         return new AirconditionA();    
        20.     }    
        21. }    
        22. //宝马523系列  
        23. public class FactoryBMW523 implements AbstractFactory {    
        24.     
        25.      @Override    
        26.     public Engine createEngine() {      
        27.         return new EngineB();    
        28.     }    
        29.     @Override    
        30.     public Aircondition createAircondition() {    
        31.         return new AirconditionB();    
        32.     }    
        33.   
        34.   
        35. }   
      • 客户:

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class Customer {    
        2.     public static void main(String[] args){    
        3.         //生产宝马320系列配件  
        4.         FactoryBMW320 factoryBMW320 = new FactoryBMW320();    
        5.         factoryBMW320.createEngine();  
        6.         factoryBMW320.createAircondition();  
        7.             
        8.         //生产宝马523系列配件    
        9.         FactoryBMW523 factoryBMW523 = new FactoryBMW523();    
        10.         factoryBMW320.createEngine();  
        11.         factoryBMW320.createAircondition();  
        12.     }    
        13. }  
    • 建造者模式http://blog.csdn.net/jason0539/article/details/44992733
      • 意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
      • 适用性:当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时;当构造过程必须允许被构造的对象有不同的表示时。
        • 1、Builder:为创建一个产品对象的各个部件指定抽象接口。
        • 2、ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
        • 3、Director:构造一个使用Builder接口的对象,指导构建过程。
        • 4、Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
      • 角色Builder:
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public interface PersonBuilder {  
        2.      void buildHead();  
        3.      void buildBody();  
        4.      void buildFoot();  
        5.      Person buildPerson();  
      •                          
        角色ConcreteBuilder:
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class ManBuilder implements PersonBuilder {  
        2.      Person person;  
        3.      public ManBuilder() {  
        4.           person = new Man();  
        5.      }  
        6.      public void buildbody() {  
        7.           person.setBody("建造男人的身体");  
        8.      }  
        9.      public void buildFoot() {  
        10.           person.setFoot("建造男人的脚");  
        11.      }  
        12.      public void buildHead() {  
        13.           person.setHead("建造男人的头");  
        14.      }  
        15.      public Person buildPerson() {  
        16.           return person;  
        17.      }  
        18. }  

        角色ConcreteBuilder:
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class WomanBuilder implements PersonBuilder {  
        2.      Person person;  
        3.      public WomanBuilder() {  
        4.           person = new Woman();  
        5.      }  
        6.      public void buildbody() {  
        7.           person.setBody(“建造女人的身体");  
        8.      }  
        9.      public void buildFoot() {  
        10.           person.setFoot(“建造女人的脚");  
        11.      }  
        12.      public void buildHead() {  
        13.           person.setHead(“建造女人的头");  
        14.      }  
        15.      public Person buildPerson() {  
        16.           return person;  
        17.      }  
        18. }  

        角色Director:
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class PersonDirector {  
        2.      public Person constructPerson(PersonBuilder pb) {  
        3.           pb.buildHead();  
        4.           pb.buildBody();  
        5.           pb.buildFoot();  
        6.           return pb.buildPerson();  
        7.      }  
        8. }  

        角色Product:
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class Person {  
        2.      private String head;  
        3.      private String body;  
        4.      private String foot;  
        5.   
        6.      public String getHead() {  
        7.           return head;  
        8.      }  
        9.      public void setHead(String head) {  
        10.           this.head = head;  
        11.      }  
        12.      public String getBody() {  
        13.           return body;  
        14.      }  
        15.      public void setBody(String body) {  
        16.           this.body = body;  
        17.      }  
        18.      public String getFoot() {  
        19.           return foot;  
        20.      }  
        21.      public void setFoot(String foot) {  
        22.           this.foot = foot;  
        23.      }  
        24. }  
        25. public class Man extends Person {  
        26.      public Man(){  
        27.           System.out.println(“开始建造男人");  
        28.      }  
        29. }  
        30. public class Woman extends Person {  
        31.      public Woman(){  
        32.           System.out.println(“开始建造女人");  
        33.      }  
        34. }  
      •      
        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class Test{  
        2.      public static void main(String[] args) {  
        3.           PersonDirector pd = new PersonDirector();  
        4.           Person womanPerson = pd.constructPerson(new ManBuilder());  
        5.           Person manPerson = pd.constructPerson(new WomanBuilder());  
        6.      }  
        7. }  



    • 单例模式http://blog.csdn.net/jason0539/article/details/23297037
      • 意图:确保某一个类中只有一个实例,而且自行实例化并向系统提供这个实例。
      • 适用性:当类智能有一个实例而且客户可以从一个众所周知的访问点访问它时;当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
      • 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。
      • 懒汉式不能保证线程安全
        1. //懒汉式单例类.在第一次调用的时候实例化自己   
        2. public class Singleton {  
        3.     private Singleton() {}  
        4.     private static Singleton single=null;  
        5.     //静态工厂方法   
        6.     public static Singleton getInstance() {  
        7.          if (single == null) {    
        8.              single = new Singleton();  
        9.          }    
        10.         return single;  
        11.     }  
        12. }  


      • 懒汉式的修改
        1.在getInstance方法上加同步

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public static synchronized Singleton getInstance() {  
        2.          if (single == null) {    
        3.              single = new Singleton();  
        4.          }    
        5.         return single;  
        6. }  
      •  

        2、双重检查锁定

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public static Singleton getInstance() {  
        2.         if (singleton == null) {    
        3.             synchronized (Singleton.class) {    
        4.                if (singleton == null) {    
        5.                   singleton = new Singleton();   
        6.                }    
        7.             }    
        8.         }    
        9.         return singleton;   
        10.     }  
         

        3、静态内部类

        [java]  view plain  copy  print ? 在CODE上查看代码片 派生到我的代码片
        1. public class Singleton {    
        2.     private static class LazyHolder {    
        3.        private static final Singleton INSTANCE = new Singleton();    
        4.     }    
        5.     private Singleton (){}    
        6.     public static final Singleton getInstance() {    
        7.        return LazyHolder.INSTANCE;    
        8.     }    
        9. }    
                              


      • 饿汉式可以保证线程安全                           
        1. //饿汉式单例类.在类初始化时,已经自行实例化   
        2. public class Singleton1 {  
        3.     private Singleton1() {}  
        4.     private static final Singleton1 single = new Singleton1();  
        5.     //静态工厂方法   
        6.     public static Singleton1 getInstance() {  
        7.         return single;  
        8.     }  
        9. }  
        饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
      • 饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了,而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。
    • 原型模式
      • 意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。clone方法
      • 适用性:当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者当一个类的实例只能有几个不同状态组合中的一种时。
  • 工厂方法模式VS建造者模式
    • 如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。
  • 抽象工厂模式VS建造者模式
    • 奔驰宝马车的例子。
    • 抽象工厂模式比建造者模式的尺度要大,关注产品整体;建造者模式关注构建过程,如车的轮胎、引擎。



  • 结构类模式
    • 适配器模式
      • 意图:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配无法在一起工作的两个类能够在一起工作。
      • 适用性:你想使用一个已经存在的类,而它的接口不符合你的需求;你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作;你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
    • 桥梁模式
      • 意图:将抽象和实现解耦,使得两者可以独立地变化。
      • 适用性:你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
    • 组合模式
      • 意图:将对象组合成树形结构以表示部分-整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
      • 适用性:你想表示对象的部分-整体层次结构。你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
    • 装饰模式
      • 意图:动态地给一个的对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。
      • 适用性:在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。处理那些可以撤消的职责。当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
    • 门面模式:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。
      • - 为一个复杂子系统提供一个简单接口
      • - 提高子系统的独立性
      • - 在层次化结构中,可以使用Facade模式定义系统中每一层的入口。
    • 享元模式
      • 意图:使用共享对象可有效地支持大量的细粒度的对象。
      • 适用性:一个应用程序使用了大量的对象。完全由于使用大量的对象,造成很大的存储开销。对象的大多数状态都可变为外部状态。如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
    • 代理模式:为其他对象提供一个代理以控制对这个对象的访问。
  • 代理模式VS装饰模式
    • 代理模式把当前的行为或功能委托给其他对象,代理类负责接口限定。例子:AOP
    • 装饰模式加强类的功能,保证被修饰的对象功能比原始对象丰富。例子:java.io.*包中
  • 装饰模式VS适配器模式
    • 装饰模式不改变类的行为和属性,只是增加;适配器模式是两个不同对象的转化
    • 装饰模式装饰的对象必须是自己的 同宗,也就是相同的接口或父类;适配器模式则必须是两个不同的对象
    • 装饰模式容易扩展


  • 行为类模式
    • 责任链模式:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
    • 命令模式:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
    • 解释器模式:给定一种语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
    • 迭代器模式:提供一种方法访问一个容器对象中各个元素,而不需暴露该对象的 内部细节
    • 中介者模式:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
    • 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
    • 观察者模式:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
    • 状态模式:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
    • 策略模式:定义一组算法, 将每个算法都封装起来,并且使它们之间可以互换。
    • 模板方法模式:定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
    • 访问者模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
  • 命令模式VS策略模式
    • 策略模式关心的是算法是否可以相互替换
    • 命令模式的主旨是封装命令, 让请求者和实现者解耦。
  • 策略模式VS状态模式
    • 策略模式封装不同的算法,算法之间没有交互,可以自由切换;状态模式封装的是不同的状态,以达到状态切换行为随之发生改变的目的。
    • 策略模式和状态模式都有一个叫做Context环境角色的类。但是策略模式的环境角色只是一个委托作用,负责算法的替换;状态模式的环境角色还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为随之切换的任务。
  • 观察者模式VS责任链模式
    • DNS解析的例子。
    • 责任链模式不改变消息对象的结构;触发链模式中允许变化
    • 责任链模式中上下节点没有关系,都是接收相同对象;触发链模式上下级关系亲密


  •  策略模式 VS桥梁模式
    • 策略模式是一个行为模式,封装一系列行为;桥梁模式在不破坏封装的情况下如何抽取出它的抽象部分和实现部分
  • 门面模式VS中介者模式
    • 中介者模式增加一个中介者,每个同事类的职位、工资、税收都只与中介者通信,中介者封装了各个同事类之间的逻辑关系。
    • 门面模式对子系统起封装作用,它可以提供一个统一的对外服务接口


  •      包装模式包括:装饰模式、适配器模式、门面模式、代理模式、桥梁模式


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值