Java 中一般认为有23种设计模式, 下面介绍几种常见的设计模式。总体来说设计模式分为三大类: 
- 创建型模式, 共5五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 
 
- 结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 
 
- 行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
 
1.单例模式
所谓的单例设计指的是一个类只允许产生一个实例化对象。
最好理解的一种设计模式,分为懒汉式和饿汉式。
饿汉式: 构造方法私有化,外部无法产生新的实例化对象,只能通过static方法取得实例化对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | class Singleton {     
 
      private static Singleton instance = new Singleton();     
 
      private Singleton() {
      }     
 
      public static Singleton getInstance() {         return instance;     } }
  | 
 
懒汉式: 当第一次去使用Singleton对象的时候才会为其产生实例化对象的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | class Singleton {     
 
      private static volatile Singleton singleton = null;
      
 
      private Singleton() {
      }     public static Singleton getInstance() {                  if (singleton == null) {             synchronized (Singleton.class) {                 if (singleton == null) {                     singleton = new Singleton();                 }             }         }         return singleton;     } }
  | 
 
	当多个线程并发执行 getInstance() 方法时,懒汉式会存在线程安全问题,所以用到了 synchronized 来实现线程的同步,当一个线程获得锁的时候其他线程就只能在外等待其执行完毕。而饿汉式则不存在线程安全的问题。
适用场景:
    单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:
    (1) 需要频繁实例化然后销毁的对象。
    (2) 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
    (3) 有状态的工具类对象。
    (4) 频繁访问数据库或文件的对象。
以下都是单例模式的经典使用场景:
    (1) 资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
    (2) 控制资源的情况下,方便资源之间的互相通信。如线程池等。 
2.观察者模式
一个对象(subject)被其他多个对象(observer)所依赖。则当一个对象变化时,发出通知,其它依赖该对象的对象都会收到通知,并且随着变化。 
3.装饰者模式
对已有的业务逻辑进一步的封装, 使其增加额外的功能, 要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。
适用环境:
	(1) 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
	(2) 处理那些可以撤消的职责。
	(3) 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的 子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
4.适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
5.工厂模式
5.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 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
   |  abstract class Car {     public void run();       public void stop(); }  
  class Benz implements Car {     public void run() {         System.out.println("Benz开始启动了。。。。。");     }       public void stop() {         System.out.println("Benz停车了。。。。。");     } }   class Ford implements Car {     public void run() {         System.out.println("Ford开始启动了。。。");     }       public void stop() {         System.out.println("Ford停车了。。。。");     } }  
  class Factory {     public static Car getCarInstance(String type) {         Car c = null;         if ("Benz".equals(type)) {             c = new Benz();         }         if ("Ford".equals(type)) {             c = new Ford();         }         return c;     } }   public class Test {       public static void main(String[] args) {         Car c = Factory.getCarInstance("Benz");         if (c != null) {             c.run();             c.stop();         } else {             System.out.println("造不了这种汽车。。。");         }     }
 
  | 
 
5.2 工厂方法模式
设计一个工厂的接口,你想要什么东西,就写个类继承于这个工厂,这样就不用修改什么,直接添加就行了。就相当于,我这个工厂是用来生汽车的,而要什么品牌的汽车具体分到了每个车间,如果新多了一种品牌的汽车,直接新增一个车间就行了。那么问题又来了,如果想要生产大炮怎么办?
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
   |  public interface Moveable {     void run(); }  
  public class Plane implements Moveable {     @Override     public void run() {         System.out.println("plane....");     } }   public class Broom implements Moveable {     @Override     public void run() {         System.out.println("broom.....");     } }  
  public abstract class VehicleFactory {     abstract Moveable create(); }  
  public class PlaneFactory extends VehicleFactory {     public Moveable create() {         return new Plane();     } }   public class BroomFactory extends VehicleFactory {     public Moveable create() {         return new Broom();     } }  
  public class Test {     public static void main(String[] args) {         VehicleFactory factory = new BroomFactory();         Moveable m = factory.create();         m.run();     } }
 
  | 
 
5.3 抽象工厂模式
与工厂方法模式不同的是,工厂方法模式中的工厂只生产单一的产品,而抽象工厂模式中的工厂生产多个产品
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
   |  public abstract class AbstractFactory {     public abstract Vehicle createVehicle();     public abstract Weapon createWeapon();     public abstract Food createFood(); }
  public class DefaultFactory extends AbstractFactory{     @Override     public Food createFood() {         return new Apple();     }     @Override     public Vehicle createVehicle() {         return new Car();     }     @Override     public Weapon createWeapon() {         return new AK47();     } }
  public class Test {     public static void main(String[] args) {         AbstractFactory f = new DefaultFactory();         Vehicle v = f.createVehicle();         v.run();         Weapon w = f.createWeapon();         w.shoot();         Food a = f.createFood();         a.printName();     } }
 
  |