模式是在特定环境下人们解决某类重复出现问题的一套成功或有效的解决方案 
在软件开发生命周期的每一个阶段都存在着一些被认同的模式
 
什么是设计模式  
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。
 
设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素,其中关键要素是模式名称、问题、解决方案和效果 
 
设计模式分为三类:5种创建型模式 、7种结构型模式 、11种行为型模式 
 
23种设计模式  
**创建型模式:**单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
**结构型模式:**适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
**行为型模式:**模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
复习的时候,发现了一个很有趣的开源代码:https://github.com/youlookwhat/DesignPattern 
 
设计模式的六大原则  
**1.开闭原则:**对扩展开放,对修改关闭;
 
**2.里氏替换原则:**任何基类可以出现的地方,子类一定可以出现 
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为
 
依赖倒转原则:  开闭原则的基础;针对接口变成,依赖于抽象而不依赖于具体;
 
**接口隔离原则:**使用多个隔离的接口,比使用单个接口要好
 
**最少知道原则:**一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立(高内聚低耦合)
 
**合成复用原则:**尽量使用合成/聚合的方式,而不是使用继承
 
 
创建型模式  
单例模式  
单例模式,保证JVM中只有一个单例对象并且该对象只有一个实例存在;
好处:  
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
**坏处:**之前看过内存溢出相关的文章,单例模式的滥用似乎很容易发生内存溢出;
eg:(栗子来自于:http://blog.csdn.net/zhangerqing/article/details/8194653 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public  class  Singleton  {	 	private  static  Singleton instance = null ; 	 	private  Singleton ()  {} 	 	public  static  Singleton getInstance ()  { 		synchronized  (instance) {                   if  (instance == null ) {                       instance = new  Singleton();                   }               }   		return  instance; 	} 	 	public  Object readResolce ()  { 		return  instance; 	} } private  static  class  SingletonFactory  {                   private  static  Singleton instance = new  Singleton();                }                public  static  Singleton getInstance ()  {                    return  SingletonFactory.instance;                }  } 
 
可以利用内部类来维护单例的实现: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  class  Singleton   {                private  Singleton ()   {       }                 private  static  class  SingletonFactory   {           private  static  Singleton instance = new  Singleton();       }                 public  static  Singleton getInstance ()   {           return  SingletonFactory.instance;       }                 public  Object readResolve ()   {           return  getInstance();       }   } 
 
工厂模式  
工厂模式分为:普通工厂模式,多个工厂模式,静态工厂模式
普通工厂模式  
建立一个工厂类,对实现了同一接口的一些类进行实例的创建
eg:来自:http://blog.csdn.net/zhangerqing/article/details/8194653 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public  interface  Sender  {	public  void  Send ()  ; } public  class  MailSender  implements  Sender  {	@Override  	public  void  Send ()  { 		... 	} } public  class  SmsSender  implements  Sender  {	@Override  	public  void  Send ()  { 		... 	} } / ** / * Factory: ** / public  class  SendFactory  {	 	public  Sender produce (String type)  { 		if ("mail" .equals(type)){ 			 			return  new  MailSender(); 		 		}else  if ("sms" .equals(type)){ 			retrun new SmsSender ()  ; 		}else { 			... 			return  null ; 		} 	} } public  class  FactoryTest  {	public  static  void  main (String[] args)  { 		SendFactory factory = new  SendFactory(); 		Sender sender = factory.produce("sms" )';  		sender.Send(); 	} } 
 
多个工厂方法模式  
对普通工厂方法模式的费劲,在普通工厂方法模式中,如果传递的字符串出错,则不能创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象
eg:将Factory修改为:
1 2 3 4 5 6 7 8 9 10 public  class  SendFactory  {	public  Sender produceMail ()  { 		return  new  MailSender(); 	} 	publc Sender produceSms ()  { 		return  new  SmsSender(); 	} } 
 
静态工厂方法模式:  
将工厂类中的方法设为静态,不需要创建实例;
 
抽象工厂模式  
普通的工厂方法,类的创建以来于工厂类;扩展程序的时候,需要对工厂类进行修改;
抽象工厂模式,创建多个工厂类,在增加新的功能的时候没直接增加新的工厂类,不需要修改之前的代码;
eg:利用刚才的两个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public  interface  Provider   {      public  Sender produce ()  ;   }   public  class  SendMailFactory  implements  Provider   {             @Override        public  Sender produce ()  {           return  new  MailSender();       }   }   public  class  SendSmsFactory  implements  Provider  {         @Override        public  Sender produce ()   {           return  new  SmsSender();       }   } public  class  Test   {         public  static  void  main (String[] args)   {           Provider provider = new  SendMailFactory();           Sender sender = provider.produce();           sender.Send();       }   } 
 
建造者模式(Builder)  
建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到的
 
感觉安卓开发的过程中,好像很经常会用到Builder这个东西;比如说okhttp的FormBody的构造;
eg:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public  class  Builder   {             private  List<Sender> list = new  ArrayList<Sender>();              public  void  produceMailSender (int  count)  {           for (int  i=0 ; i<count; i++){               list.add(new  MailSender());           }       }              public  void  produceSmsSender (int  count)  {           for (int  i=0 ; i<count; i++){               list.add(new  SmsSender());           }       }   }   public  class  Test   {         public  static  void  main (String[] args)   {           Builder builder = new  Builder();           builder.produceMailSender(10 );       }   } 
 
 
还有另一种形式(在effective Java中看到的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 public  class  NutritionFacts   {      private  final  int  servingSize;       private  final  int  servings;       private  final  int  calories;       private  final  int  fat;       private  final  int  sodium;       private  final  int  carbohydrate;          public  static  class  Builder   {                    private  final  int  servingSize;           private  final  int  servings;                       private  int  calories      = 0 ;           private  int  fat           = 0 ;           private  int  carbohydrate  = 0 ;           private  int  sodium        = 0 ;              public  Builder (int  servingSize, int  servings)   {               this .servingSize = servingSize;               this .servings    = servings;           }              public  Builder calories (int  val)                 { calories = val;      return  this ; }          public  Builder fat (int  val)                 { fat = val;           return  this ; }          public  Builder carbohydrate (int  val)                 { carbohydrate = val;  return  this ; }          public  Builder sodium (int  val)                 { sodium = val;        return  this ; }             public  NutritionFacts build ()   {               return  new  NutritionFacts(this );           }       }          private  NutritionFacts (Builder builder)   {           servingSize  = builder.servingSize;           servings     = builder.servings;           calories     = builder.calories;           fat          = builder.fat;           sodium       = builder.sodium;           carbohydrate = builder.carbohydrate;       }          public  static  void  main (String[] args)   {           NutritionFacts cocaCola = new  NutritionFacts.Builder(240 , 8 ).               calories(100 ).sodium(35 ).carbohydrate(27 ).build();       }   } 
 
在类的内部定义一个Builder内部类,通过Builder中的函数,设置对象的各种值,最后build为我们的类对象; 
感觉这个跟平时开发中用到的东西比较像;
我觉得,利用Builder模式,就解决了多个构造函数的问题 
原型模式  
该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象
eg:栗子来自:http://blog.csdn.net/zhangerqing/article/details/8194653 
1 2 3 4 5 6 7 8 9 10 11 12 / ** / * 原型类 / ** public  class  Prototype  implements  Cloneable   {         public  Object clone ()  throws  CloneNotSupportedException  {           Prototype proto = (Prototype) super .clone();           return  proto;       }   } 
 
一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称(Cloneable接口是个空接口,你可以任意定义实现类的方法名)
Object类中,clone()是native的
 
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。 
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public  class  Prototype  implements  Cloneable , Serializable   {         private  static  final  long  serialVersionUID = 1L ;       private  String string;          private  SerializableObject obj;                 public  Object clone ()  throws  CloneNotSupportedException  {           Prototype proto = (Prototype) super .clone();           return  proto;       }                 public  Object deepClone ()  throws  IOException, ClassNotFoundException  {                         ByteArrayOutputStream bos = new  ByteArrayOutputStream();           ObjectOutputStream oos = new  ObjectOutputStream(bos);           oos.writeObject(this );                         ByteArrayInputStream bis = new  ByteArrayInputStream(bos.toByteArray());           ObjectInputStream ois = new  ObjectInputStream(bis);           return  ois.readObject();       }          public  String getString ()   {           return  string;       }          public  void  setString (String string)   {           this .string = string;       }          public  SerializableObject getObj ()   {           return  obj;       }          public  void  setObj (SerializableObject obj)   {           this .obj = obj;       }      }      class  SerializableObject  implements  Serializable   {      private  static  final  long  serialVersionUID = 1L ;   } 
 
 
结构型模式  
适配器模式  
将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作
eg:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public  class  Mobile    {              public  void  inputPower (V5Power power)         {          int  provideV5Power = power.provideV5Power();           System.out.println("手机(客户端):我需要5V电压充电,现在是-->"  + provideV5Power + "V" );       }   }   public  interface  V5Power    {      public  int  provideV5Power ()  ;   } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 public  class  V220Power    {              public  int  provideV220Power ()         {          System.out.println("我提供220V交流电压。" );           return  220  ;        }   } 
 
适配器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  V5PowerAdapter  implements  V5Power    {              private  V220Power v220Power ;              public  V5PowerAdapter (V220Power v220Power)         {          this .v220Power = v220Power ;       }          @Override        public  int  provideV5Power ()         {          int  power = v220Power.provideV220Power() ;                    System.out.println("适配器:我悄悄的适配了电压。" );           return  5  ;        }           } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 / ** / * Test / ** public  class  Test    {      public  static  void  main (String[] args)         {          Mobile mobile = new  Mobile();           V5Power v5Power = new  V5PowerAdapter(new  V220Power()) ;            mobile.inputPower(v5Power);       }   } 
 
桥接模式  
将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
主要特点是把抽象(abstraction)与行为实现(implementation)分离开来 
Client Bridge模式的使用者
Abstraction 抽象类接口(接口或抽象类);维护对行为实现(Implementor)的引用
Refined Abstraction Abstraction子类
Implementor 行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作)
ConcreteImplementor Implementor子类
eg:栗子来自:http://blog.csdn.net/shaopeng5211/article/details/8827507 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 / ** / * implemeentor / * 行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作) / ** public  interface  Engine  {	public  void  installEngine ()  ; } / ** / * ConcreteImplemeentor / * Implementor子类 / ** public  class  Engine2000  implements  Engine  {	@Override  	public  void  installEngine ()  { 		... 	} } public  class  Engine2200  implements  Engine  {	@Override  	public  void  installEngine ()  { 		... 	} } / ** / * Abstraction / * 抽象类接口(接口或抽象类);维护对行为实现(Implementor)的引用 / ** public  abstract  class  Car  {	private  Engine engine; 	publc Car (Engine engine)  { 		this .engine = engine; 	} 	public  Engine getEngine ()  { 		return  engine; 	} 	public  void  setEngine (Engine engine)  { 		this .engine = engine; 	} 	public  abstract  void  installEngine ()  ; } / ** / * Refined Abstraction / * Abstraction子类 / ** public  class  Bus  extends  Car  {	public  Bus (Engine engine)  { 		super (engine); 	} 	@Override  	public  void  installEngine ()  { 		... 		this .getEngine().installEngine(); 	} } public  class  Jeep  extends  Car   {         public  Jeep (Engine engine)   {           super (engine);       }       @Override        public  void  installEngine ()   {           System.out.print("Jeep:" );           this .getEngine().installEngine();       }      }  / ** / * Client / * Bridge模式的使用者 / ** public  class  MainClass  {	public  static  void  main (String args[])  { 		Engine engine2000 = new  Engine2000();           Engine engine2200 = new  Engine2200();                      Car bus = new  Bus(engine2000);           bus.installEngine();                      Car jeep = new  Jeep(engine2200);           jeep.installEngine();   	} } 
 
感觉桥接模式,有点像……画画的时候,有各种笔,然后颜料也有各种颜色;然后不同的笔可以蘸不同的颜料;
装饰者模式  
若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上
当我们设计好了一个类,我们需要给这个类添加一些辅助的功能,并且不希望改变这个类的代码,这时候就是装饰者模式大展雄威的时候了
 
体现了开闭原则 
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/24269409  
这个博主用了游戏系统中装备加宝石,提升属性当做栗子,感觉很有意思;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70    public  interface  IEquip    {                 public  int  caculateAttack ()  ;                  public  String description ()  ;   }      public  class  ArmEquip  implements  IEquip    {         @Override        public  int  caculateAttack ()         {          return  20 ;       }          @Override        public  String description ()         {          return  "屠龙刀" ;       }      }      public  class  RingEquip  implements  IEquip    {         @Override        public  int  caculateAttack ()         {          return  5 ;       }          @Override        public  String description ()         {          return  "圣战戒指" ;       }      } 
 
装饰器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123    public  interface  IEquipDecorator  extends  IEquip    {         }      public  class  BlueGemDecorator  implements  IEquipDecorator    {              private  IEquip equip;          public  BlueGemDecorator (IEquip equip)         {          this .equip = equip;       }          @Override        public  int  caculateAttack ()         {          return  5  + equip.caculateAttack();       }          @Override        public  String description ()         {          return  equip.description() + "+ 蓝宝石" ;       }      }      public  class  YellowGemDecorator  implements  IEquipDecorator    {              private  IEquip equip;          public  YellowGemDecorator (IEquip equip)         {          this .equip = equip;       }          @Override        public  int  caculateAttack ()         {          return  10  + equip.caculateAttack();       }          @Override        public  String description ()         {          return  equip.description() + "+ 黄宝石" ;       }      }      public  class  RedGemDecorator  implements  IEquipDecorator    {              private  IEquip equip;          public  RedGemDecorator (IEquip equip)         {          this .equip = equip;       }          @Override        public  int  caculateAttack ()         {          return  15  + equip.caculateAttack();       }          @Override        public  String description ()         {          return  equip.description() + "+ 红宝石" ;       }      }   package  com.zhy.pattern.decorator;     public  class  Test    {      public  static  void  main (String[] args)         {                   System.out.println(" 一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器" );           equip = new  RedGemDecorator(new  BlueGemDecorator(new  YellowGemDecorator(new  ArmEquip())));           System.out.println("攻击力  : "  + equip.caculateAttack());           System.out.println("描述 :"  + equip.description());           System.out.println("-------" );       }   } 
 
组合模式  
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
外观模式  
提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/25837275 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public  class  HomeTheaterFacade    {      private  Computer computer;       private  Player player;       private  Light light;       private  Projector projector;       private  PopcornPopper popper;          public  HomeTheaterFacade (Computer computer, Player player, Light light, Projector projector, PopcornPopper popper)         {          this .computer = computer;           this .player = player;           this .light = light;           this .projector = projector;           this .popper = popper;       }          public  void  watchMovie ()         {                      popper.on();           popper.makePopcorn();           light.down();           projector.on();           projector.open();           computer.on();           player.on();           player.make3DListener();       }              public  void  stopMovie ()         {          popper.off();           popper.stopMakePopcorn();           light.up();           projector.close();           projector.off();           player.off();           computer.off();       }   } 
 
感觉像是,将要做一件事的所有步骤,整合到一块;
享元模式  
享元模式采用一个共享来避免大量拥有相同内容对象的开销;享元模式以共享的方式高效地支持大量的细粒度对象
像String型,就是享元模式的;
代理模式  
为其他对象提供一种代理以控制对这个对象的访问
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
 
**抽象角色:**声明真实对象和代理对象的共同接口;
**代理角色:**代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
**真实角色:**代理角色所代表的真实对象,是我们最终要引用的对象。
静态代理  
eg:栗子来自《Java与模式》
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72    public  abstract  class  Subject   {      public  abstract  void  request ()  ;   }      public  class  RealSubject  extends  Subject   {         @Override        public  void  request ()   {                   }      }      public  class  ProxySubject  extends  Subject   {             private  RealSubject realSubject = null ;                      @Override        public  void  request ()   {           preRequest();                      if (realSubject == null ){               realSubject =  new  RealSubject();           }           realSubject.request();                      postRequest();       }                  private  void  postRequest ()   {                           }                  private  void  preRequest ()   {                           }   }      public  class  Main   {      public  static  void  main (String[] args)   {           Subject subject = new  ProxySubject();           subject.request();       }   } 
 
动态代理  
Java动态代理类位于Java.lang.reflect包下
ge:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 package  dynamicproxy;        public  interface  Subject   {      void  request ()  ;   }         public  class  RealSubject  implements  Subject   {         @Override        public  void  request ()   {                   }      }   import  java.lang.reflect.InvocationHandler;  import  java.lang.reflect.Method;        public  class  DynamicSubject  implements  InvocationHandler   {         private  Object sub;         public  DynamicSubject (Object sub)   {           this .sub = sub;       }          @Override        public  Object invoke (Object proxy, Method method, Object[] args)  throws  Throwable  {           System.out.println("before calling "  + method);            method.invoke(sub,args);            System.out.println("after calling "  + method);            return  null ;        }      }   import  java.lang.reflect.Constructor;  import  java.lang.reflect.InvocationHandler;  import  java.lang.reflect.Proxy;     public  class  Main   {      public  static  void  main (String[] args)  throws  Throwable  {           RealSubject rs = new  RealSubject();           InvocationHandler handler = new  DynamicSubject(rs);           Class cls = rs.getClass();                                                    Subject subject = (Subject)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(), handler);           subject.request();       }   } 
 
 
行为型模式  
模版方法模式  
定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤
模版方法定义了一个算法的步骤,并且允许子类为一个或多个步骤提供实现
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/26276093  
博主的WorkDay栗子;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 public  abstract  class  Worker    {      protected  String name;          public  Worker (String name)         {          this .name = name;       }                  public  final  void  workOneDay ()         {             System.out.println("-----------------work start ---------------" );           enterCompany();           computerOn();           work();           computerOff();           exitCompany();           System.out.println("-----------------work end ---------------" );          }                  public  abstract  void  work ()  ;                  private  void  computerOff ()         {          System.out.println(name + "关闭电脑" );       }                  private  void  computerOn ()         {          System.out.println(name + "打开电脑" );       }                  public  void  enterCompany ()         {          System.out.println(name + "进入公司" );       }                  public  void  exitCompany ()         {          System.out.println(name + "离开公司" );       }      }   / * * codeMokey / *  public  class  ITWorker  extends  Worker    {         public  ITWorker (String name)         {          super (name);       }          @Override        public  void  work ()         {          System.out.println(name + "写程序-测bug-fix bug" );       }      }   public  class  HRWorker  extends  Worker    {         public  HRWorker (String name)         {          super (name);       }          @Override        public  void  work ()         {          System.out.println(name + "看简历-打电话-接电话" );       }      }   public  class  Test    {      public  static  void  main (String[] args)         {             Worker it1 = new  ITWorker("鸿洋" );           it1.workOneDay();           Worker it2 = new  ITWorker("老张" );           it2.workOneDay();           Worker hr = new  HRWorker("迪迪" );           hr.workOneDay();           Worker qa = new  QAWorker("老李" );           qa.workOneDay();           Worker pm = new  ManagerWorker("坑货" );           pm.workOneDay();          }   } 
 
命令模式  
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象
将请求封装成对象,将动作请求者和动作执行者解耦
 
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/24602057 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247    public  class  Door    {      public  void  open ()         {          System.out.println("打开门" );       }          public  void  close ()         {          System.out.println("关闭门" );       }      }      public  class  Light    {      public  void  on ()         {          System.out.println("打开电灯" );       }          public  void  off ()         {          System.out.println("关闭电灯" );       }   }      public  class  Computer    {      public  void  on ()         {          System.out.println("打开电脑" );       }              public  void  off ()         {          System.out.println("关闭电脑" );       }   }   public  interface  Command    {      public  void  execute ()  ;   }      public  class  LightOffCommond  implements  Command    {      private  Light light ;               public  LightOffCommond (Light light)         {          this .light = light;       }          @Override        public  void  execute ()         {          light.off();       }      }      public  class  LightOnCommond  implements  Command    {      private  Light light ;               public  LightOnCommond (Light light)         {          this .light = light;       }          @Override        public  void  execute ()         {          light.on();       }      }      public  class  ComputerOnCommond  implements  Command    {      private  Computer computer ;               public  ComputerOnCommond ( Computer computer)         {          this .computer = computer;       }          @Override        public  void  execute ()         {          computer.on();       }      }      public  class  ComputerOffCommond  implements  Command    {      private  Computer computer ;               public  ComputerOffCommond ( Computer computer)         {          this .computer = computer;       }          @Override        public  void  execute ()         {          computer.off();       }                    }      public  class  ControlPanel    {      private  static  final  int  CONTROL_SIZE = 9 ;       private  Command[] commands;          public  ControlPanel ()         {          commands = new  Command[CONTROL_SIZE];                       for  (int  i = 0 ; i < CONTROL_SIZE; i++)           {               commands[i] = new  NoCommand();           }       }                  public  void  setCommand (int  index, Command command)         {          commands[index] = command;       }                  public  void  keyPressed (int  index)         {          commands[index].execute();       }      }   public  class  NoCommand  implements  Command    {      @Override        public  void  execute ()         {         }      }   public  class  Test    {      public  static  void  main (String[] args)         {                      Light light = new  Light();           Door door = new  Door();           Computer computer = new  Computer();                       ControlPanel controlPanel = new  ControlPanel();                    controlPanel.setCommand(0 , new  LightOnCommond(light));           controlPanel.setCommand(1 , new  LightOffCommond(light));           controlPanel.setCommand(2 , new  ComputerOnCommond(computer));           controlPanel.setCommand(3 , new  ComputerOffCommond(computer));           controlPanel.setCommand(4 , new  DoorOnCommond(door));           controlPanel.setCommand(5 , new  DoorOffCommond(door));                       controlPanel.keyPressed(0 );           controlPanel.keyPressed(2 );           controlPanel.keyPressed(3 );           controlPanel.keyPressed(4 );           controlPanel.keyPressed(5 );           controlPanel.keyPressed(8 );                      }   } 
 
迭代器模式  
提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节
**抽象容器:**一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
**具体容器:**就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
**抽象迭代器:**定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove();
**迭代器实现:**实现迭代器接口中定义的方法,完成集合的迭代。
eg:栗子来自:http://blog.csdn.net/zhengzhb/article/details/7610745 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 interface  Iterator   {      public  Object next ()  ;       public  boolean  hasNext ()  ;   }   class  ConcreteIterator  implements  Iterator  {      private  List list = new  ArrayList();       private  int  cursor =0 ;       public  ConcreteIterator (List list)  {           this .list = list;       }       public  boolean  hasNext ()   {           if (cursor==list.size()){               return  false ;           }           return  true ;       }       public  Object next ()   {           Object obj = null ;           if (this .hasNext()){               obj = this .list.get(cursor++);           }           return  obj;       }   }   interface  Aggregate   {      public  void  add (Object obj)  ;       public  void  remove (Object obj)  ;       public  Iterator iterator ()  ;   }   class  ConcreteAggregate  implements  Aggregate   {      private  List list = new  ArrayList();       public  void  add (Object obj)   {           list.add(obj);       }          public  Iterator iterator ()   {           return  new  ConcreteIterator(list);       }          public  void  remove (Object obj)   {           list.remove(obj);       }   }   public  class  Client   {      public  static  void  main (String[] args)  {           Aggregate ag = new  ConcreteAggregate();           ag.add("小明" );           ag.add("小红" );           ag.add("小刚" );           Iterator it = ag.iterator();           while (it.hasNext()){               String str = (String)it.next();               System.out.println(str);           }       }   } 
 
观察者模式  
定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/24179699 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125    public  interface  Subject    {              public  void  registerObserver (Observer observer)  ;                  public  void  removeObserver (Observer observer)  ;                  public  void  notifyObservers ()  ;      }      public  interface  Observer    {      public  void  update (String msg)  ;      }   import  java.util.ArrayList;  import  java.util.List;     public  class  ObjectFor3D  implements  Subject    {      private  List<Observer> observers = new  ArrayList<Observer>();               private  String msg;          @Override        public  void  registerObserver (Observer observer)         {          observers.add(observer);       }          @Override        public  void  removeObserver (Observer observer)         {          int  index = observers.indexOf(observer);           if  (index >= 0 )           {               observers.remove(index);           }       }          @Override        public  void  notifyObservers ()         {          for  (Observer observer : observers)           {               observer.update(msg);           }       }                  public  void  setMsg (String msg)         {          this .msg = msg;                      notifyObservers();       }      }   public  class  Observer1  implements  Observer    {         private  Subject subject;          public  Observer1 (Subject subject)         {          this .subject = subject;           subject.registerObserver(this );       }          @Override        public  void  update (String msg)         {          System.out.println("observer1 得到 3D 号码  -->"  + msg + ", 我要记下来。" );       }      }   public  class  Test    {      public  static  void  main (String[] args)         {                   ObjectFor3D subjectFor3d = new  ObjectFor3D();                    Observer observer1 = new  Observer1(subjectFor3d);           Observer observer2 = new  Observer2(subjectFor3d);              subjectFor3d.setMsg("20140420的3D号码是:127"  );           subjectFor3d.setMsg("20140421的3D号码是:333"  );                  }   } 
 
中介者模式  
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互
**抽象中介者:**定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
**中介者实现类:**从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。
**同事类:**如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如有六个同事类对象,假如对象1发生变化,会有4个对象受到影响。如果对象2发生变化,那么会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
 
如果引入中介者模式,那么同事类之间的关系将变为星型结构,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
 
eg:栗子来自:http://blog.csdn.net/jason0539/article/details/45216585 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 bstract class  AbstractColleague   {         protected  int  number;              public  int  getNumber ()   {             return  number;         }              public  void  setNumber (int  number)  {             this .number = number;         }              public  abstract  void  setNumber (int  number, AbstractColleague coll)  ;     }     class  ColleagueA  extends  AbstractColleague  {        public  void  setNumber (int  number, AbstractColleague coll)   {             this .number = number;             coll.setNumber(number*100 );         }     }     class  ColleagueB  extends  AbstractColleague  {                 public  void  setNumber (int  number, AbstractColleague coll)   {             this .number = number;             coll.setNumber(number/100 );         }     }    abstract  class  AbstractMediator   {        protected  AbstractColleague A;         protected  AbstractColleague B;                  public  AbstractMediator (AbstractColleague a, AbstractColleague b)   {             A = a;             B = b;         }              public  abstract  void  AaffectB ()  ;                  public  abstract  void  BaffectA ()  ;          }    class  Mediator  extends  AbstractMediator   {             public  Mediator (AbstractColleague a, AbstractColleague b)   {             super (a, b);         }                   public  void  AaffectB ()   {             int  number = A.getNumber();             B.setNumber(number*100 );         }                   public  void  BaffectA ()   {             int  number = B.getNumber();             A.setNumber(number/100 );         }     }     public  class  Client   {        public  static  void  main (String[] args)  {                  AbstractColleague collA = new  ColleagueA();             AbstractColleague collB = new  ColleagueB();                          System.out.println("==========设置A影响B==========" );             collA.setNumber(1288 , collB);             System.out.println("collA的number值:" +collA.getNumber());             System.out.println("collB的number值:" +collB.getNumber());                  System.out.println("==========设置B影响A==========" );             collB.setNumber(87635 , collA);             System.out.println("collB的number值:" +collB.getNumber());             System.out.println("collA的number值:" +collA.getNumber());         }     } 
 
中介模式能够避免类与类之间的过度耦合; 
它将类与类之间的关系转换为星型结构;
备忘录模式  
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。
 
http://www.cnblogs.com/java-my-life/archive/2012/06/06/2534942.html 
解释器模式  
给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
 
http://www.cnblogs.com/java-my-life/archive/2012/06/19/2552617.html 
状态模式  
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类
当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。
 
eg:栗子来自:http://blog.csdn.net/lmj623565791/article/details/26350617 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143    public  class  VendingMachine    {                 private  final  static  int  HAS_MONEY = 0 ;               private  final  static  int  NO_MONEY = 1 ;               private  final  static  int  SOLD = 2 ;               private  final  static  int  SOLD_OUT = 3 ;          private  int  currentStatus = NO_MONEY;               private  int  count = 0 ;          public  VendingMachine (int  count)         {          this .count = count;           if  (count > 0 )           {               currentStatus = NO_MONEY;           }       }                  public  void  insertMoney ()         {          switch  (currentStatus)           {           case  NO_MONEY:               currentStatus = HAS_MONEY;               System.out.println("成功投入硬币" );               break ;           case  HAS_MONEY:               System.out.println("已经有硬币,无需投币" );               break ;           case  SOLD:               System.out.println("请稍等..." );               break ;           case  SOLD_OUT:               System.out.println("商品已经售罄,请勿投币" );               break ;              }       }                  public  void  backMoney ()         {          switch  (currentStatus)           {           case  NO_MONEY:               System.out.println("您未投入硬币" );               break ;           case  HAS_MONEY:               currentStatus = NO_MONEY;               System.out.println("退币成功" );               break ;           case  SOLD:               System.out.println("您已经买了糖果..." );               break ;           case  SOLD_OUT:               System.out.println("您未投币..." );               break ;           }       }                  public  void  turnCrank ()         {          switch  (currentStatus)           {           case  NO_MONEY:               System.out.println("请先投入硬币" );               break ;           case  HAS_MONEY:               System.out.println("正在出商品...." );               currentStatus = SOLD;               dispense();               break ;           case  SOLD:               System.out.println("连续转动也没用..." );               break ;           case  SOLD_OUT:               System.out.println("商品已经售罄" );               break ;              }       }                  private  void  dispense ()         {             switch  (currentStatus)           {           case  NO_MONEY:           case  HAS_MONEY:           case  SOLD_OUT:               throw  new  IllegalStateException("非法的状态..." );           case  SOLD:               count--;               System.out.println("发出商品..." );               if  (count == 0 )               {                   System.out.println("商品售罄" );                   currentStatus = SOLD_OUT;               } else                {                   currentStatus = NO_MONEY;               }               break ;              }          }   } 
 
策略模式  
定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户
(代码好长啊……懒得贴了) 
传送门:http://blog.csdn.net/lmj623565791/article/details/24116745 
职责链模式(责任链模式)  
责任链模式,我记得Android的事件分发机制就是责任链模式的;
之前在学习分发机制的时候有过一些记录:Android自定义View——事件分发机制学习笔记 
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
 
有一种比较简单的解释大概是酱紫的:领导给小组长安排工作,然后小组长再把工作分配给组员;如果组员做的了就揽下来,否则反馈给组长;若组长做的了就揽下来;
**抽象处理者(Handler)角色:**定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。 
**具体处理者(ConcreteHandler)角色:**具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
eg:栗子来自:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html  
《Java与模式》
1.抽象处理者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public  abstract  class  Handler   {              protected  Handler successor;          public  abstract  void  handleRequest ()  ;          public  Handler getSuccessor ()   {         return  successor;     }          public  void  setSuccessor (Handler successor)   {         this .successor = successor;     }      } 
 
2.具体处理者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  ConcreteHandler  extends  Handler   {         @Override      public  void  handleRequest ()   {                  if (getSuccessor() != null )         {                         System.out.println("放过请求" );             getSuccessor().handleRequest();                     }else          {                         System.out.println("处理请求" );         }     }   } 
 
3.Test:
1 2 3 4 5 6 7 8 9 10 11 12 public  class  Client   {    public  static  void  main (String[] args)   {                  Handler handler1 = new  ConcreteHandler();         Handler handler2 = new  ConcreteHandler();         handler1.setSuccessor(handler2);                  handler1.handleRequest();     } } 
 
深入学习:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 
访问者模式