• 1. Java设计模式
  • 2. 开-闭原则(OCP)面向对象可利用设计(OOD)的第一块基石,就是“开-闭原则(Open-Closed principle,简称OCP),它的核心含意是:一个好的设计应该能够容纳新的功能需求的增加,但是增加的方式不是通过修改已有的模块(类),而是通过增加新的模块(类)来完成的。
  • 3. 里氏代换原则 就是子类可以代替父类出现的任何地方,在抽象的时候,理解两个类之间是什么关系很重要。经典判断:“has-A”关系,还是“Is-a”关系。在“has-a”的关系中,两个类存在的是依赖的关系(在类A里面存在类B的的变量);在“Is-a”的关系中,可以提取这两个类的“共同代码”放在抽象类C中,然后A,B继承于C,这也是一种重构。
  • 4. 依赖倒转原则 就是在我们编程的时候方法的参数类型,变量,对于其他具体类的依赖,我们尽量的使用抽象类。 就是说尽量依赖于抽象,而不是依赖于实现。
  • 5. 接口隔离原则 就是一个类对另外一个类依赖的时候,应当是建立在最小的接口上面。对于接口隔离原则来说,有两种接口,一种是真正意义上面的“java 接口”Interface;另外一种是指一个类的方法的集合。对于这来两种有,两个接口隔离的原则,对于一个类里面的方法的集合的接口隔离,我们称作是“角色隔离原则”;另外一种叫做“定制服务”。 定制服务,就是一个类,我给你这个客户端一些方法,我放在一个java接口(Interface)里面。给另外一个客户端另外一些方法,放在另外一个接口(Interface). 角色隔离原则,是指客户端要多个不同的类的方法,我们就搞几个不同类别的接口(Interface),在书中,这么比喻的,就相当于电影剧本里面的人物,我们找人来演,这个人就是具体的类。这就叫做角色隔离原则。
  • 6. 组合/聚合复用原则 就是说要尽量的使用合成和聚合,而不是继承关系达到复用的目的。      其实这里最终要的地方就是区分“has-a”和“is-a”的区别。相对于合成和聚合,继承的缺点在于:父类的方法全部暴露给子类。父类如果发生变化,子类也得发生变化。聚合的复用的时候就对另外的类依赖的比较的少。
  • 7. 最少知识原则(迪米特原则 )对于成员,private,default,protected,public。往上面走,权限越小,依赖的耦合就越小。 强调了类之间的松耦合,类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成影响,也就是信息的隐藏出尽了软件的复用。
  • 8. 模式(Pattern)一个围棋下得好的人知道,好的“形”对于围棋非常重要。形是棋子在棋盘上的几何形状的抽象化。 形就是模式(Pattern),也是人脑把握和认识外界的关键。
  • 9. 模式我们处理大量问题时,在很多不同的问题中重复出现的一种性质,它使得我们可以使用一种方法来描述问题实质并用本质上相同,但细节永不会重复的方法去解决,这种性质就叫模式。
  • 10. 成为模式的条件1、 它可以解决问题。模式不能仅仅反映问题,而必须对问题提出解决方案。 2、它所提出解决方案是正确的,而且不是很明显的。 3、它必须是涉及软件系统深层的结构的东西,不能仅是对已有的模块的描述。 4、它必须满足人的审美,简洁美观。 一个美妙的东西不一定就是模式, 但是一个模式必须是一个美妙的东西
  • 11. 经典模式总浏览创立型结构型行为型类工厂方法(Factory Method)适配器(Adapter)解释器(Interpreter) 模板方法(Template Method)对象抽象工厂(Abstract Factory) 生成器(Builder) 原型(Prototype) 单态(Singleton)适配器(Adapter) 桥接(Bridge) 组成(Composite) 装饰(Decorator) 外观(Facade) 享元(Flyweight) 代理(Proxy)责任链(Chain of Responsibility) 命令(Command) 迭代器(Iterator) 中介者(Mediator) 备忘录(Memento) 观察者(Observer) 状态(State) 策略(Strategy) 访问者(Visitor)
  • 12. 创立性模式 创立性模式(Creational Patterns)是类在实例化时使用的模式。 当一些系统在创立对象时,需要动态地决定 怎样创立对象,创立哪些对象 创立性模式告诉我们怎样构造和包装这些动态的决定。
  • 13. 结构性模式结构性模式描述类和对象怎样结合在一起成为较大的结构。 结构性模式描述两种不同的东西:类与类的实例。
  • 14. 行为模式行为模式设计到算法和对象职责间的分配。 行为模式不仅是关于类和对象的,而且还描述它们之间的作用。 这些模式刻画了运行时刻难以跟踪的复杂的控制流,它帮助软件设计者在设计软件的时候把注意力从控制流转移到对象间的联系上。
  • 15. 经典模式总浏览创立型结构型行为型类工厂方法(Factory Method)适配器(Adapter)解释器(Interpreter) 模板方法(Template Method)对象抽象工厂(Abstract Factory) 生成器(Builder) 原型(Prototype) 单态(Singleton)适配器(Adapter) 桥接(Bridge) 组成(Composite) 装饰(Decorator) 外观(Facade) 享元(Flyweight) 代理(Proxy)责任链(Chain of Responsibility) 命令(Command) 迭代器(Iterator) 中介者(Mediator) 备忘录(Memento) 观察者(Observer) 状态(State) 策略(Strategy) 访问者(Visitor)
  • 16. 简单工厂模式
  • 17. Java创建对象的方法所有面向对象的语言都有固定的创立对象的办法。java的办法就是使用new操作符。比如 StringBuffer s = new StringBuffer(1000); 使用new操作符的短处是事先必须明确知道要实例化的类是什么 实例化的责任往往与使用实例的责任不加区分。
  • 18. 创立性模式面向对象的设计的目的之一,就是把责任进行划分,以分派给不同的对象。 创立性模式把对象的创立过程封装起来,使得创立实例的责任与使用实例的责任分割开 由专门的模块分管实例的创立,而系统在宏观上不再依赖于对象创立过程的细节
  • 19. 创立性模式创立性模式将类实例化,不必事先知道每次是要实例化哪一个类 把实例化的责任与使用实例的责任分割开来
  • 20. 工厂模式工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。 工厂模式有以下几种形态: 简单工厂(Simple Factory)模式 工厂方法(Factory Method)模式 抽象工厂(Abstract Factory)模式
  • 21. 简单工厂(Simple Factory)模式比如说,你有一个描述你的后花园的系统,在你的后花园里有各种的花,但还没有水果。你现在要往你的系统里引进一些新的类,用来描述下列的水果:   葡萄 Grapes   草莓 Strawberry   萍果 Apple
  • 22. 简单工厂(Simple Factory)模式                                                                                                                                                                                    源代码源代码源代码源代码
  • 23. 简单工厂(Simple Factory)模式作为小花果园的主人兼园丁,也是系统的一部分,自然要由一个合适的类来代表,这个类就是 FruitGardener类。 源代码
  • 24. 园丁的工作(简单工厂)FruitGardener类会根据要求,创立出不同的水果类,比如萍果Apple,葡萄Grape或草莓Strawberry的实例。 这里的园丁就如同一个可以创建水果产品的工厂一样 如果接到不合法的要求,FruitGardener类会给出例外BadFruitException。                                                                      源代码
  • 25. 丰收的果园(客户端)在使用时,只须呼叫FruitGardener的factory()方法即可 try {  FruitGardener gardener = new FruitGardener();  FruitIF grape = gardener.factory("grape");  FruitIF apple = gardener.factory("apple");  FruitIF strawberry = gardener.factory("strawberry");  ...  }  catch(BadFruitException e) {   ... }
  • 26. 小结:简单工厂模式的定义总而言之,简单工厂模式就是由一个工厂类根据参数来决定创立出那一种产品类的实例。
  • 27. 小结:简单工厂模式框架的源代码 public class Creator { public Product factory() {  return new ConcreteProduct(); } } public interface Product { } public class ConcreteProduct implements Product { public ConcreteProduct(){} }
  • 28. 源代码:FruitIF接口接口FruitIF的源代码。这个接口确定了水果类必备的方法: 种植plant(),生长grow(), 以及收获harvest()。 package com.javapatterns.simplefactory; public interface FruitIF {  void grow();  void harvest();  void plant();  String color = null;  String name = null; } 返回
  • 29. 源代码:Apple类萍果是多年生木本植物,因此具备树龄treeAge性质 package com.javapatterns.simplefactory; public class Apple implements FruitIF {  public void grow() {   log("Apple is growing...");  }  public void harvest() {   log("Apple has been harvested.");  }  public void plant() {   log("Apple has been planted.");  }  public static void log(String msg) {   System.out.println(msg);  }  public int getTreeAge(){ return treeAge; }  public void setTreeAge(int treeAge){ this.treeAge = treeAge; }  private int treeAge; } 返回
  • 30. 源代码:Grape类葡萄分为有籽与无籽两种,因此具有seedful性质 package com.javapatterns.simplefactory; public class Grape implements FruitIF {  public void grow() {   log("Grape is growing...");  }  public void harvest() {   log("Grape has been harvested.");  }  public void plant() {   log("Grape has been planted.");  }  public static void log(String msg) {   System.out.println(msg);  }  public boolean getSeedful() {   return seedful;  }  public void setSeedful(boolean seedful) {   this.seedful = seedful;  }  private boolean seedful; }返回
  • 31. 源代码:Strawberry类package com.javapatterns.simplefactory;  public class Strawberry implements FruitIF {   public void grow() {    log("Strawberry is growing...");   }   public void harvest() {    log("Strawberry has been harvested.");   }   public void plant() {    log("Strawberry has been planted.");   }   public static void log(String msg) {    System.out.println(msg);   } } 返回
  • 32. 源代码:FruitGardener类package com.javapatterns.simplefactory; public class FruitGardener {  public FruitIF factory(String which) throws BadFruitException{   if ("apple".equalsIgnoreCase(which)) {    return new Apple();   }   else if ("strawberry".equalsIgnoreCase(which)) {    return new Strawberry();   }   else if ("grape".equalsIgnoreCase(which)) {    return new Grape();   }   else {    throw new BadFruitException("Bad fruit request");   }  } } 返回
  • 33. 源代码:BadFruitException类package com.javapatterns.simplefactory; public class BadFruitException extends Exception {  public BadFruitException(String msg {   super(msg);  } } 返回
  • 34. 简单工厂模式总结在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化, 如同一个交通警察站在来往的车辆流中,决定放行哪一个方向的车辆向那一个方向流动一样。
  • 35. 工厂方法模式工厂方法模式是简单工厂模式的进一步抽象化和推广。 它比简单工厂模式聪明的地方在于, 它不再作为一个具体的交通警察的面貌出现,而是以交通警察局(工厂)的面貌出现。 具体的警察成为工厂方法的执行者。 工厂方法模式里不再只由一个工厂类决定哪一个产品类应当被实例化,这个决定被交给子类去作。
  • 36. 开始种植蔬菜我们准备再次引进蔬菜类植物,比如: 西红柿 (Tomato) 土豆 (Potato) 西芥兰花 (Broccoli) 蔬菜需要喷洒(dust)杀虫剂(pesticide)除虫
  • 37. 为什么需要工厂方法模式简单工厂模式。FruitGardener掌握所有水果类的生杀大权。                                                                                               
  • 38. 为什么需要工厂方法模式为了引进蔬菜,难道再设计一个专管蔬菜类植物的工厂类 ? 这样做一个明显的不足点就是不够一般化和抽象化。 在FruitGardener和VeggieGardener类之间明显存在很多共同点, 这些共同点应当抽出来一般化和框架化。 这样一来,如果后花园的主人决定再在园子里引进些树木类植物时, 我们有框架化的处理方法。
  • 39. 工厂方法模式的定义                                                                                                                                                                
  • 40. 工厂方法模式的定义ConcreteCreator 的factory() 方法返还的数据类型是一个接口 PlantIF,而不是哪一个具体的产品类。 这种设计使得工厂类创立哪一个产品类的实例细节完全封装在工厂类内部。 工厂方法模式又叫多形性工厂模式,显然是因为实工厂类都有共同的接口,或者都有共同的抽象父类。
  • 41. 抽象工厂接口(Creator)担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何在模式中创立对象的工厂类必须实现这个接口。
  • 42. 实工厂类 (Concrete Creator) 担任这个角色的是与应用程序紧密相关的,直接在应用程序调用下,创立产品实例的那样一些类。
  • 43. 实产品 (Concrete Product) 担任这个角色的类是工厂方法模式所创立的任何对象所属的类。
  • 44. 产品 (Product) 担任这个角色的类是工厂方法模式所创立的对象的父类,或它们共同拥有的接口。
  • 45.                                                                                                                                                          源代码源代码源代码源代码源代码
  • 46. 工厂方法模式在小花果园系统中的实现(2)取代了过去的全能角色的是一个抽象的园丁,这个角色规定出具体园丁角色需要实现的具体职能,而真正负责作物管理的则是各种作物的具体园丁角色。
  • 47. 工厂方法模式在小花果园系统中的实现(2)
  • 48. 工厂方法模式应该在什么情况下使用如果在发现系统只用一个产品类等级就可以描述所有已有的产品类,简单工厂模式是很好的解决方案。 当发现系统只用一个产品类等级不足以描述所有的产品类,包括以后可能要添加的新的产品类时,就应当考虑采用工厂方法模式。 由于工厂方法模式可以容许多个实的工厂类,以每一个工厂类负责每一个产品类等级,因此这种模式可以容纳所有的产品等级。
  • 49. 父类 Gardener package com.javapatterns.factorymethod; abstract public class Gardener {  public abstract PlantIF factory(String which) throws BadFruitException; } 返回
  • 50. 子类 FruitGardener package com.javapatterns.factorymethod; public class FruitGardener extends Gardener {  public PlantIF factory(String which) {   if ("apple".equalsIgnoreCase(which)) {    return new Apple();   }   else if ("strawberry".equalsIgnoreCase(which)) {    return new Strawberry();   }   else if ("grape".equalsIgnoreCase(which)) {    return new Grape();   }   else {    throw new BadPlantException("Bad fruit request");   }}} 返回
  • 51. 蔬菜类 Broccoli package com.javapatterns.factorymethod; public class Broccoli implements VeggieIF, PlantIF {  public void grow() {   log("Broccoli is growing...");  }  public void harvest() {   log("Broccoli has been harvested.");  }  public void plant() {   log("Broccoli has been planted.");  }  private static void log(String msg) {   System.out.println(msg);  }  public void pesticideDust(){ } } 返回
  • 52. 水果类 Apple 与<简单工厂模式>一节里的Apple类相比,唯一的区别就是多实现了一个接口 PlantIF。其它的水果类与 Apple 相似,因此不再赘述。 package com.javapatterns.factorymethod; public class Apple implements FruitIF, PlantIF {  public void grow() {   log("Apple is growing...");  }  public void harvest() {   log("Apple has been harvested.");  }  public void plant() {   log("Apple has been planted.");  }  private static void log(String msg) {   System.out.println(msg);  }  public int getTreeAge(){ return treeAge; }  public void setTreeAge(int treeAge){ this.treeAge = treeAge; }  private int treeAge; } 返回
  • 53. 例外类 BadPlantException package com.javapatterns.factorymethod; public class BadPlantException extends Exception {  public BadPlantException(String msg) {   super(msg);  } }
  • 54. 抽象工厂模式抽象工厂模式是所有形态的工厂模式中最为抽象和最具广泛性的一种形态。 抽象工厂模式是工厂方法模式的进一步扩广化和抽象化
  • 55. 抽象工厂模式                                                                                                                                                                             
  • 56. 抽象工厂模式在抽象工厂模式中,抽象产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个产品族(Product Family)。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。
  • 57. 抽象工厂模式的位图在只有一个产品族时,第三维就坍缩掉,位图也就只剩下两维。这时抽象工厂模式就退化得与工厂方法模式一模一样。                                                                                                                                        
  • 58. 抽象工厂模式
  • 59. 抽象工厂模式在小花果园系统中的实现                                                                                                                                                     
  • 60. 抽象工厂模式在小花果园系统中的实现源代码源代码源代码源代码源代码
  • 61. 抽象工厂模式在小花果园系统中的实现两处花园就相当于两个产品族。显然,给北方花园的植物是要种植在一起的,给南方花园的植物是要另种植在一起的。这种分别应当体现在系统的设计上面。
  • 62. 抽象工厂(AbstractFactory)类或接口 担任这个角色的是模式的核心,它是与应用程序无关的。任何在模式中创立对象的工厂类必须实现这个接口,或继承这个类。
  • 63. 实工厂类 (Concrete Factory) 担任这个角色的是与应用程序紧密相关的,直接在应用程序调用下,创建产品实例或者使用工厂方法创建产品实例的那样一些类。
  • 64. 抽象产品 (Abstract Product) 担任这个角色的类是工厂方法模式所创立的对象的父类,或它们共同拥有的接口。
  • 65. 实产品 (Concrete Product) 担任这个角色的类是工厂方法模式所创立的任何对象所属的类。
  • 66. 接口 Gardener package com.javapatterns.abstractfactory; public interface Gardener {} 返回
  • 67. 实工厂类 NorthenGardener package com.javapatterns.abstractfactory; public class NorthenGardener implements Gardener {  public VeggieIF createVeggie(String name) { return new NorthernVeggie(name); }  public FruitIF createFruit(String name) { return new NorthernFruit(name); } } 返回
  • 68. 实工厂类 TropicalGardener package com.javapatterns.abstractfactory; public class TropicalGardener implements Gardener {  public VeggieIF createVeggie(String name) { return new TropicalVeggie(name); }  public FruitIF createFruit(String name) { return new TopicalFruit(name); } } 返回
  • 69. 接口 VeggieIF package com.javapatterns.abstractfactory; public interface VeggieIF {} 返回
  • 70. 实产品类 NorthernVeggie 实产品类 NorthernFruit 与此极为类似,故略去。 package com.javapatterns.abstractfactory; public class NorthernVeggie implements VeggieIF {  public NorthernVeggie(String name) { this.name = name; }  public String getName(){ return name; }  public void setName(String name){ this.name = name; }  private String name; } 返回
  • 71. 实产品类 TropicalVeggie 实产品类 TropicalFruit 与此极为类似,故略去。 package com.javapatterns.abstractfactory; public class TropicalVeggie implements VeggieIF {  public TropicalVeggie(String name) { this.name = name;}  public String getName(){ return name; }  public void setName(String name){ this.name = name; }  private String name; }返回
  • 72. 总结1.简单工厂模式 “开-闭”原则要求模块允许新产品加入系统中,无需对现有代码进行修改在简单工厂中,对于产品的消费者是成立的,对于工厂是不成立的,每次增加一个新产品,都要修改工厂角色但是产品的消费者可以避免修改 2.工厂方法模式     工厂方法中,具体工厂类都有共同的接口,它们“生产”出很多的处于一个等级结构中的产品对象使用这个设计的系统可以允许向系统加入新的产品类型,而不必修改已有的代码,只需要加入一个新的具体的工厂就OK了,所以对增加新的产品而言,完全支持“开-闭”原则 3.抽象工厂模式 抽象工厂模式封装了产品对象的家族的可变性,从而可以使系统动态决定将那一个产品族的产品实例化,另一方面可以在新的产品对象引进到已有的系统中时不必修改,在产品对象家族变化时,可以维持系统的"开-闭"原则
  • 73. 单态模式 一个单态类只可有一个实例。这样的类常用来进行资源管理。 例如:很多软件都有数据库,一般而言, 整个软件应当使用一个联接通道,而不是任意在需要时就新打开一个联接通道。
  • 74. 单态类的特性 1、单态类只可有一个实例。 2、它必须自己创立自己这唯一的一个实例。 3、它必须给所有其它的类提供自己这一实例。   最后,单态类在理论和实践上都并非限定只能有"一个"实例,而是很容易推广到任意有限个实例的情况。
  • 75. 单态模式的几种实现饿汉式单态类                                                                                                                    
  • 76. 饿汉式单态类 由于构造器是私有的,因此此类不能被继承 package com.javapatterns.singleton.demos; public class EagerSingleton { private EagerSingleton() { } public static EagerSingleton getInstance() {   return m_instance; } private static final EagerSingleton m_instance = new EagerSingleton(); }
  • 77. 懒汉式单态类 懒汉式单态类在第一次被引用时将自己实例化。                                                                                         
  • 78. 懒汉式单态类构造子是私有的,因此此类不能被继承 public class LazySingleton { private LazySingleton() {} /** * 静态工厂方法,返还此类的唯一实例。因为创建实例的时候, * 涉及到资源初始化,所以最好使用同步机制。 */ synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton(); } return m_instance; } private static LazySingleton m_instance = null; }
  • 79. 两种单态类的比较饿汉式单态类在自己被加载时就将自己实例化。 单从资源利用效率角度来讲,这是比懒汉式单态类稍差些。 从速度和反应时间角度来 讲,则比懒汉式单态类稍好些。 懒汉式单态类在实例化时必须处理好在多个线程同时首次引用此类时,实例化函数内部关键段的访问限制问题。
  • 80. 责任链模式
  • 81. 从击鼓传花谈起击鼓者将花传给贾母,开始传花游戏。花由贾母传给贾赦,由贾赦传给贾政,由贾政传给贾宝玉,又由贾宝玉传给贾环,由贾环传回给贾母,如此往复(见下图)。当鼓声停止时,手中有花的人就得执行酒令 .
  • 82. 责任链模式很多的对象由每一个对象对其下家的引用而联接起来形成一条链。 请求在这个链上传递,直到链上的某一个对象决定处理此请求。 发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求 责任链可能是一条直线、一个环链甚至一个树结构的一部分。
  • 83. 抽象处理者(Handler)角色 定义出一个处理请求的接口;如果需要,接口可以定义出一个方法,以返回对下家的引用。下图给出了一个示意性的类图:
  • 84. 具体处理者(ConcreteHandler)角色 接到请求后,可以选择将请求处理掉,或者将请求传给下家。下图给出了一个示意性的类图。
  • 85. 击鼓传花系统的类图源代码源代码源代码
  • 86. 责任链模式的静态类结构
  • 87. 纯的责任链模式 一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个: 一是承担责任 二是把责任推给下家 纯的责任链模式的实际例子很难找到 某一个具体处理者对象在承担了一部分责任后又把责任向下传 ,一个请求可以最终不被任何接受端对象所接受。
  • 88. 举例:AWT事件浮升机制事件首先传播到它所发生的部件上,然后向其父类处理器传播。 容器可以选择处理这个事件,或者再将此事件向更高一级的父类处理器传播。 事件如此一级级地向上传播,就像水底的气泡一点一点地冒到水面上一样,因此又叫做事件浮升机制。 AWT库里处理事件的代码
  • 89. 举例:AWT库里处理事件的代码 public boolean action(Event event, Object obj) {     if (event.target == btnOK){       doOKBtnAction();      }     else if (event.target == btnExit) {       doExitBtnAction();      }     else {       return super.action(event, obj);      }     return true;   } AWT1.1的事件处理模型于1.0相比有了很大的变化。新的事件处理模型是建立在观察者模式的基础之上的,而不再是责任链模式的基础之上的。 返回
  • 90. 举例:AWT库里处理事件的缺点AWT1.0的事件处理的模型是基于继承的,会导致很多的子类,在一个面向对象的系统里,经常使用的应当是委派。 由于每一个事件都会沿着部件树结构向上传播,因此事件浮升机制会使得事件的处理变得较慢。
  • 91. 链结构的由来 责任链模式并不创建出责任链。责任链的创建必须由系统的其它部分完成。 在下面的图中,责任链是一个树结构的一部分。
  • 92. 小结:墨子论责任和责任链的传播
  • 93. 源代码:抽象处理者abstract class Player {   abstract public void handle(int i);//处理方法   private Player successor;   public Player() { successor = null;} protected void setSuccessor(Player aSuccessor) {   successor = aSuccessor; } public void next(int index) {//传递方法   if( successor != null ) {     successor.handle(index);    }   else {     System.out.println("Program terminated.");    }   } } 返回
  • 94. 源代码:具体处理者class JiaMu extends Player {    public JiaMu(Player aSuccessor) {     this.setSuccessor(aSuccessor);    }    public void handle(int i) {     if( i == 1 ) {      System.out.println("Jia Mu gotta drink!");     }     else {      System.out.println("Jia Mu passed!"); next(i);     }    }   } 返回
  • 95. 源代码:客户端的public class DrumBeater {   private static Player player;   static public void main(String[] args)    {     player = new JiaMu( new JiaShe( new JiaZheng( new JiaBaoYu(new JiaHuan(null))))); //规定由第4个处理者处理请求     player.handle(4);    } } 返回
  • 96. 变压器模式的介绍变压器模式把一个类的接口变换成客户端所期待的另一种接口。 变压器模式使原本无法在一起工作的两个类能够在一起工作。 变压器模式是关于类结构的结构性模式,因而是静态的模式。
  • 97. 类形式的变压器模式的定义类的适配器模式把被适配类的API转换成目标类的API源代码源代码源代码
  • 98. 说明目标(Target)。这就是我们所期待得到的接口。 源(Adaptee)。现有需要适配的接口。 变压器(Adapter)。变压器类是本模式的核心。变压器把源接口转换成目标接口。显然,这一角色不可以是接口, 而必须是实类。 由于变压器类是源的子类,因此可以在变压器类中置换(override)掉源的一些方法。
  • 99. 对象形式的变压器模式对象的适配器模式不是使用继承关系连接到Adaptee类, 而是使用委派关系连接到Adaptee类。源代码
  • 100. 举例:指方为圆 MagicFinger类实现了BallF接口,并同时扩展了Cube类,充当了适配器的角色。源代码源代码源代码
  • 101. 举例:指方为圆说明使用的是实例形式的变压器模式。 如果一旦我们决定不仅要支持正方体, 而且要支持四面体等多面体,我们可以使用同一个MagicFinger类,而不必针对每一个多面体都建立一个MagicFinger类。
  • 102. 小结在以下情况下使用使配器模式: 系统需要使用现有的类,而此类的接口不符合系统的需要
  • 103. 源代码:Targetpackage com.javapatterns.adapter.classAdapter; public interface Target { /* 这是源类也有的方法sampleOperation1 */ void sampleOperation1(); /* 这是源类没有的方法sampleOperation2 */ void sampleOperation2(); } 返回
  • 104. 源代码:Adapteepackage com.javapatterns.adapter.classAdapter; public class Adaptee { /** *源类含有方法sampleOperation1 */ public void sampleOperation1(){} } 返回
  • 105. 源代码:Adapterpackage com.javapatterns.adapter.classAdapter; public class Adapter extends Adaptee implements Target { /* 由于源类没有方法 sampleOperation2 , * 因此适配器类补充上这个方法。 */ public void sampleOperation2() { } } 返回
  • 106. 源代码:Adapter (2)package com.javapatterns.adapter; public class Adapter implements Target { public Adapter(Adaptee adaptee){ super(); this.adaptee = adaptee; } /*源类有方法sampleOperation1因此适配器类直接委派即可 */ public void sampleOperation1(){ adaptee.sampleOperation1(); } /*源类没有方法sampleOperation2因此适配器类需要补充此方法 */ public void sampleOperation2(){ // Write your code here } private Adaptee adaptee; } 返回
  • 107. 源代码:Cube类package com.javapatterns.adapter.cube2ball; public class Cube { public Cube(double width) { this.width = width; } public double calculateVolume() { return width * width * width; } public double calculateFaceArea() { return width * width; } public double getWidth() { return this.width; } public void setWidth(double width) { this.width = width; } private double width; } 返回
  • 108. 源代码:BallIF接口package com.javapatterns.adapter.cube2ball; public interface BallIF { double calculateArea(); double calculateVolume(); double getRadius(); void setRadius(double radius); } 返回
  • 109. 源代码:MagicFinger类public class MagicFinger implements BallIF { public MagicFinger(Cube adaptee) { super(); this.adaptee = adaptee; radius = adaptee.getWidth(); } public double calculateArea() { return PI * 4.0D * ( radius * radius ); } public double calculateVolume() { return PI * 4.0D/3.0D * ( radius * radius * radius ); } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } private double radius = 0; private static final double PI = 3.14D; private Cube adaptee; } 返回
  • 110. 观察者模式观察者模式(Observer)是对象的行为模式,又称: 发布-订阅模式(Publish/Subscribe)、 源-监听器(Source/Listener)
  • 111. 观察者模式观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。 这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新
  • 112. 观察者模式类图                                                                                                                                                                                        源代码源代码源代码源代码
  • 113. 抽象主题(Subject)角色 主题角色把所有的观察者对象的引用保存在一个列表里;每个主题都可以有任何数量的观察者。 主题提供一个接口可以加上或撤销观察者对象;主题角色又叫做抽象被观察者(Observable)角色;                                                   
  • 114. 具体主题(ConcreteSubject)角色 保存对具体观察者对象有用的内部状态; 在这种内部状态改变时给其观察者发出一个通知; 具体主题角色又叫作具体被观察者角色;                                                        
  • 115. 具体观察者(ConcreteObserver)角色保存一个指向具体主题对象的引用; 具体观察者角色实现抽象观察者角色所要求的更新自己的接口,以便使本身的状态与主题的状态自恰。
  • 116. 观察者模式在Java中从AWT1.1开始视窗系统的事件模型采用观察者模式,因此观察者模式在Java语言里的地位较为重要。 在Java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。
  • 117. Java观察者模式类图
  • 118. Observable类 被观察者类都是java.util.Observable类的子类                                                                          
  • 119. Observer接口package java.util; public interface Observer { /** * 当被观察的对象发生变化时,这个方法会被调用。 */ void update(Observable o, Object arg); }
  • 120. 举例被观察者对象叫做Watched,也就是被监视者; 观察者对象叫做Watcher,也就是监视人的意思。 Watched对象继承自java.util.Observable Watcher对象实现了java.util.Observer接口 对象Test,扮演客户端角色
  • 121. 举例类图源代码源代码源代码
  • 122. 小结一个软件系统里面包含了各种对象,就像一个欣欣向荣的森林充满了各种生物一样。在一片森林中,各种生物彼此依赖和约束,形成一个个生物链。 一个生物的状态变化会造成其他一些生物的相应行动,每一个生物都处在别的生物的互动之中。
  • 123. 源代码:Subject接口public interface Subject { public void attach(Observer observer); public void detach(Observer observer); void notifyObservers(); } attach() 用来增加一个观察者对象; detach() 用来删除一个观察者对象; notifyObservers() 用来通知各个观察者刷新它们自己。 返回
  • 124. 源代码:ConcreteSubject类import java.util.Vector; import java.util.Enumeration; public class ConcreteSubject implements Subject { public void attach(Observer observer) { observersVector.addElement(observer); } public void detach(Observer observer) { observersVector.removeElement(observer); } public void notifyObservers() { Enumeration enumeration = observers(); while (enumeration.hasMoreElements()) { ((Observer)enumeration.nextElement()).update(); } } public Enumeration observers() { return ((Vector) observersVector.clone()).elements(); } private Vector observersVector = new java.util.Vector(); } 返回
  • 125. 源代码:Observer接口public interface Observer { void update(); } 返回
  • 126. 源代码:ConcreteObserver类public class ConcreteObserver implements Observer { public void update() { // Write your code here } } 返回
  • 127. 源代码:Tester.javaimport java.util.Observer; public class Tester { static private Watched watched; static private Observer watcher; public static void main(String[] args) { watched = new Watched(); watcher = new Watcher(watched); watched.changeData("In C, we create bugs."); watched.changeData("In Java, we inherit bugs."); watched.changeData("In Java, we inherit bugs."); watched.changeData("In Visual Basic, we visualize bugs."); } }返回
  • 128. 源代码:Watched.javaimport java.util.Observable; public class Watched extends Observable { private String data = ""; public String retrieveData() { return data; } public void changeData(String data) { if (!this.data.equals(data)) { this.data = data; setChanged(); } notifyObservers(); } }返回
  • 129. 源代码:Watcher.javaimport java.util.Observable; import java.util.Observer; public class Watcher implements Observer { public Watcher(Watched w) { w.addObserver(this); } public void update(Observable ob, Object arg) { System.out.println("Data has been changed to: '" + ( (Watched) ob).retrieveData() + "'"); } } 返回
  • 130. 门面(Facade)模式门面模式是结构模式,外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式。
  • 131. 医院的例子
  • 132. 医院的解决方案
  • 133. 什么是门面模式门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面对象进行。门面模式通过一个高层次的接口,是的子系统更易于使用。
  • 134. 示意图子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。
  • 135. 门面模式的实现如果一个系统有好几个子系统,每一个子系统都可以有一个门面类,整个系统可以有数个门面类。
  • 136. 举例一个保安系统由两个录像机,三个电灯、一个遥感器和一个警报器组成。 操作人员要经常启动和关闭这些仪器。
  • 137. 举例:不使用门面模式的设计源代码源代码源代码源代码源代码
  • 138. 举例:使用门面模式的设计源代码源代码
  • 139. 小结使用门面模式我们可以: 为一个复杂的系统提供一个简单的接口。 保持子系统的独立性。 构建层次化系统,使用Façade定义每一层的入口。
  • 140. 源代码Alarm.javapackage com.javapatterns.facade.securityfacade; public class Alarm { public void activate() { System.out.println("Activating the alarm."); } public void deactivate() { System.out.println("Deactivating the alarm."); } public void ring() { System.out.println("Ring the alarm."); } public void stopRing() { System.out.println("Stop the alarm."); } }返回
  • 141. 源代码Camera.javapackage com.javapatterns.facade.securityfacade; public class Camera { public void turnOn() { System.out.println("Turning on the camera."); } public void turnOff() { System.out.println("Turning off the camera."); } public void rotate(int degrees) { System.out.println("Rotating the camera by " + degrees + " degrees."); } }返回
  • 142. 源代码ClientFacade.javapackage com.javapatterns.facade.securityfacade; public class Client { /** * @link aggregation * @directed */ private static SecurityFacade security; public static void main(String[] args) { security.activate(); } }返回
  • 143. 源代码Client.javapublic class Client { static private Camera camera1, camera2; static private Light light1, light2, light3; static private Sensor sensor; static private Alarm alarm; public static void main(String[] args) { camera1.turnOn(); camera2.turnOn(); light1.turnOn(); light2.turnOn(); light3.turnOn(); sensor.activate(); alarm.activate(); } } 返回
  • 144. 源代码Light.javapackage com.javapatterns.facade.securityfacade; public class Light { public void turnOn() { System.out.println("Turning on the light."); } public void turnOff() { System.out.println("Turning off the light."); } public void changeBulb() { System.out.println("Changing the light-bulb."); } } 返回
  • 145. 源代码Sensor.javapackage com.javapatterns.facade.securityfacade; public class Sensor { public void activate() { System.out.println("Activating on the sensor."); } public void deactivate() { System.out.println("Deactivating on the sensor."); } public void trigger() { System.out.println("The sensor has been triggered."); } } 返回
  • 146. 源代码SecurityFacade.javapublic class SecurityFacade { private Camera camera1, camera2; private Light light1, light2, light3; private Sensor sensor; private Alarm alarm; public void activate() { camera1.turnOn(); camera2.turnOn(); light1.turnOn(); light2.turnOn(); light3.turnOn(); sensor.activate(); alarm.activate(); } public void deactivate() { //。。。 } }返回