Java之常用设计模式(精简)

话不多说奔主题,精神抖擞就是干! Java中共包含23种设计模式,大致分为三种类型:1 创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原

话不多说奔主题,精神抖擞就是干!

 

Java中共包含23种设计模式,大致分为三种类型:
1. 创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。

2. 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

3. 行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式。

 

下面介绍常用的几种:

1. 单例模式:是个程序一般都会用到这个模式。比如日志类,整个项目工程可能只需要创建一次,重复创建也只是返回第一次创建的实例的引用。

//饿汉模式

public class HungrySingleTon implement Serializable{

  // 保证序列化和反序列化时的对象的兼容性

  static  final long serialVersion = 42L;

  //快加载,利用了JVM类的懒加载机制保证线程安全

  private static final HungrySingleTon singleTon = new HungrySingleTon();

  private HungrySingleTon()

  {

    //防止利用反射来生成实例,破坏单例机制

    if (singleTon != null) {

      throw new RunTimeException("单例禁止反射");

    }

  };

  public static HungrySingleTon GetInstance() { return singleTon; }

}

//静态内部类,利用了JVM类的懒加载机制保证线程安全

public class SingleTon {

  private static class InnerSingleTon {

    private static SingleTon singleTon = new SingleTon();

  }

  private SingleTon() {

    //防止利用反射来生成实例,破坏单例机制

    if (singleTon != null) {

      throw new RunTimeException("单例禁止反射");

    }

  };

  public static SingleTon  GetInstance() { return InnerSingleTon.singleTon; }

}

//懒汉模式

public class LazySingleTon {

  //利用 volatile 禁止指令重排,保证线程之间可见性和一致性

  private static volatile LazySingleTon singleTon = null;

  private LazySingleTon() {};

  //懒加载,利用 synchronized 保证线程间的原子性

  public static LazySingleTon GetInstance() {

    if (null == singleTon) {

      synchronized (LazySingleTon.class) {

        if (null == singleTon) {

          singleTon = new LazySingleTon();

        }

      }

    }

    return singleTon;

   }

}

*要点:构造函数私有化,new前双次判空加锁。

 

2. 工厂模式:集中化生产同一类产品(存在差异化),比如造车厂,我可能只造小轿车,但是小轿车可能有不同的颜色搭配,还有经济型、标准型、豪华型等性能搭配。

2.1 简单工厂

public class Car {

  public Color color;  //颜色

  public Car (Color color) { this.color = color; }

}

public class PianYiCar extends Car {

  public PianYICar(Color color) { super.color = color; }

}

public class XiaoZiCar  extends Car {

  public XiaoZiCar  (Color color) { super.color = color; }

}

public class GuiCar  extends Car {

  public GuiCar  (Color color) { super.color = color; }

}

public class CarFactory {

  public Car Create(Type type, Color color) {

    switch(type) {

      case '经济型': return new PianYiCar (color);

      case '标准型': return new XiaoZiCar  (color);

      case '豪华型': return new GuiCar(color);

      default: return new Car(color);

    }

  }

}

*要点:简单工厂,其实就是条件工厂,根据不同条件去创建同一类型的差异化对象。

 

2.2 工厂方法:定义一个工厂类该类定义了一些标准方法但没有具体实现,通过不同的子类继承这个工厂父类并实现其标准方法去创造相同(存在差异化)或不同类型的对象。

//开闭原则

public  abstract class CarFactory {

  public abstract Car CreateCar(Color color);

}

//单一职责原则

public class PianYiCarFactory {

  @Override

  public Car CreateCar(Color color) {new PianYiCar(color); }

}

public class XiaoZiCarFactory {

  @Override

  public Car CreateCar(Color color) {new XiaoZiCar(color); }

}

public class GuiCarFactory {

  @Override

  public Car CreateCar(Color color) {new GuiCar(color); }

}

*要点:具体实施的工作不再由父工厂去完成,父工厂定义了行业标准,而子工厂根据老大说的标准,各自去完成自己的事情。

 

2.3 抽象工厂模式:由方法工厂组合演变而来

public interface IConn {

  public IConn getConn();

}

public interface IComm {

  public IComm getComm();

}

public interface IDataBaseUtils {

  public IConn getConn();

  public IComm getComm();

}

public class MySqlDataBase implement IDataBaseUtils {

  public IConn getConn() {

    system.out.println("mysql connected");

  }

  public IComm getComm() {

    system.out.println("mysql command");

  }

}

public class OracleDataBase implement IDataBaseUtils {

  public IConn getConn() {

    system.out.println("oracle connected");

  }

  public IComm getComm() {

    system.out.println("oracle command");

  }

}

 

3. 建造者模式

//使用场景:对象具有复杂结构,内部具有依赖关系顺序

public class Product {

  private final string proName;

  private final string part1;

  private final string part2;

  public Product(string proName, string part1, string part2) {

    this.proName = proName;

    this.part1 = part1;

    this.part2 = part2;

  }

  public class Builder { 

    private string proName;

    private string part1;

    private string part2;

    public Builder proName(string proName) { this.proName = proName; return this; }

    public Builder part1(string part1) { this.part1 = part1; return this; }

    public Builder part2(string part2) { this.part2 = part2; return this; }

  }

  public Product build () { return new Product(this.proName, this.part1, this.part2); }

}

调用

Product product = new Product.Builder().proName("Car").part1("1").part2("2").build();

*要点:建造者独立,便于扩展,内部细节可控。

 

4. 适配器模式

4.1 类适配器

先讲个小故事。大家在日常生活里,有没有遇到过这种情况,我的手机快没电了想要充电,但是手头只有一个二插头的充电器和一个三插头的插线板,woc,怎么办?好急啊!在线等~

那这种情况下我们是不是可以采取一些极端手段,比如把二插头的充电器的两只腿掰弯,这样是不是就能插进三插头的插线板里充电了呢?哈哈哈,没错,我真是个天才!

public Interface TwoChong {

  public void  TwoChongDian();

}

public Interface ThreeChong {

  public void  ThreeChongDian();

}

public class TwoChongImpl implements TwoChong {

  @Override

  public void TwoChongDian() { System.out.println("充电"); }

}

//下面这个就是你掰弯后的二插头充电器了^-^

public class TwoChongImplEx extends TwoChongImpl implements ThreeChong {

  @Override

  public void ThreeChongDian() { super.TwoChongDain(); }

}

*要点:其实说白了,就是对现有功能的一种扩展。

 

4.2 对象适配器:它是对类适配器的一种衍生,因为类适配具有强绑定、强约束性,调用污染,不方便扩展。

public class ThreeChongImpl implements ThreeChong {

  private TwoChongImpl twoChongImpl = null;

  public ThreeChongImpl(TwoChongImpl twoChongImpl) { this.twoChongImpl = twoChongImpl; }

  @Override

  public  void ThreeChongDian() { twoChongImpl.TwoChongDian(); }

}

 

4.3 接口适配器:减少代码量,提高可读性。

 public interface A {

  public void Do();

}

public class AA implements A {

  @Override

  public void Do() {}

}

public class AAA extends AA {

  @Override

  public void Do() { System.out.println("实际工作"); }

}

 

5. 装饰者模式:扩展功能可以组合叠加,互相直接没有干扰。

public interface Phone {

  public void operate();

}

public class IPhone1 implement Phone {

  @Override

  public void operate() { system.out.println("拍照"); }

}

public class IPhone2 implement Phone {

  Phone phone;

  public IPhone2(Phone phone) {this.phone = phone; }

  @Override

  public void operate() {

    system.out.println("美颜");

    phone.operate();

  }

}

public class IPhone3 implement Phone {

  Phone phone;

  public IPhone3(Phone phone) {this.phone = phone; }

  @Override

  public void operate() {

    system.out.println("滤镜");

    phone.operate();

  }

}

调用:

Phone phone = new IPhone3(new IPhone2(new IPhone1()));

输出:

滤镜

美颜

拍照

 

6. 代理模式:代理模式分为三种,静态代理,JDK动态代理,CGLIB动态代理。代理模式是Spring中面向切面编程的核心。

6.1 静态代理

public interface Wo {

  public void Travel();

}

public class WoImpl implements Wo {

  @Override

  public void Travel() { Sysyem.out.println("去旅行"); }

}

public class MyProxyImpl implements Wo {

  private WoImpl woImpl = null;

  public MyProxyImpl(WoImpl woImpl) { this.woImpl = woImpl; } 

  @Override

  public void Travel() {

    Sysyem.out.println("订去返机票");

    Sysyem.out.println("打车去机场");

    woImpl.Travel();

  }

}

*要点:所谓代理就是在你执行某个动作前后,帮你做一些准备动作和收尾动作。静态代理类只能用于一个类的代理,扩展性差。

 

6.2 JDK动态代理

public class MyProxyImpl {
  public static Wo getMyProxyByJDK(Wo wo) {
    Wo myProxy = (Wo) Proxy.newProxyInstance(wo.getClass().getClassLoader(),
      wo.getClass().getInterfaces(),
      new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

          System.out.println("订去返机票");

          System.out.println("打车去机场");

          Object obj = method.invoke(wo, args);
          return obj;
        }
      });
    return myProxy ;
  }
}

 

7. 模板方法模式

先讲个小故事。大家在日常生活里,有空的时候都会自己做点饭吃。那么今天我想做个炒饭吃,明天我想做个炒面吃。其实炒饭和炒面基本上做法是一样的,只是主要食材不一样。

那么我只要能把炒饭做好了,炒面自然不在话下。

public abstract class ChaoTemplate {

  public void Do() {

    DaoYou();

    KaiHuo();

    ReYou();

    DaoShiCai();

    FanChao();

    GuanHuo();

  }

 

  public void DaoYou() { System.out.println("倒油"); }

  public void KaiHuo() { System.out.println("开火"); }

  public void ReYou() { System.out.println("热油"); }

  public abstract void DaoShiCai();

  public void FanChao() {System.out.println("翻炒"); }

  public void GuanHuo() { System.out.println("关火"); }

}

public  class ChaoFan extends ChaoTemplate {

  @Override

  public void DaoShiCai() { System.out.println(" 倒米饭"); }

}

public  class ChaoMian extends ChaoTemplate {

  @Override

  public void DaoShiCai() { System.out.println("倒面条"); }

}

public class Test {

  public static main(String[] args) {

    ChaoFan chaoFan = new ChaoFan();

    ChaoMian chaoMian = new ChaoMian();

    chaoFan.Do();

    chaoMian.Do();

  }

}

 *要点:其实就是将相同的动作提取出来放到父类里去实现,子类实现各自的不同工作。减少重复劳动。

 

8. 策略模式:定义一系列方法簇,具体实现类可以自己选择组合不同方法簇里的方法

public interface IMoveable {

  public void move();

}

public class OneStepOneMove implement IMoveable{

  @Override

  public void move() { system.out.println("一步一步走"); }

}

public class SpaceStepMove implement IMoveable{

  @Override

  public void move() { system.out.println("太空步"); }

}

public interface Biteable {

  public void bite();

}

public class OneStepOneBite implement Biteable{

  @Override

  public void bite() { system.out.println("一下一下咬"); }

}

public class HeadBite implement Biteable{

  @Override

  public void bite() { system.out.println("头撞"); }

}

public abstract class Zombie {

  public Zombie(IMoveable moveable, IBiteable biteable) {

    this.moveable = moveable;

    this.biteable = biteable;

  }

  private IMoveable moveable;

  private IBiteable biteable;

  public abstract void display();

  public void move() { moveable.move(); }

  public void bite() { biteable.bite(); }

}

public PuTongZombie extend Zombie {

  public PuTongZombie(IMoveable moveable, IBiteable biteable) {

    super(moveable, biteable);

  }

  @Override

  public void display() { system.out.println("我是普通僵尸"); }

}

public BigZombie extend Zombie {

  public PuTongZBigZombieMoveable moveable, IBiteable biteable) {

    super(moveable, biteable);

  }

  @Override

  public void display() { system.out.println("我是大头僵尸"); }

}

 public class Test {

  public static void main(String[] args) {

    Zombie putongZombie = new PuTongZombie(new OneStepOneBite(), new OneStepOneBite());

    Zombie bigZombie = new BigZombie(new HeadBite(), new SpaceStepBite());

    putongZombie.display();

    putongZombie.move();

    putongZombie.bite();

    bigZombie.display();

    bigZombie.move();

    bigZombie.bite();

  }

}

输出:

我是普通僵尸

一步一步走

一下一下咬

我是大头僵尸

太空步

头撞

 

欢迎看官儿们留言补充和指正,谢谢下次见!

标签: 我是 我想 是个