设计模式之禅总结(持续更新)

设计模式

最近在看设计模式之禅,总结一下23种模式

单例模式

案例引入

我是皇帝,天底下只能由我一个,唯我独尊

具体代码

懒汉式

public class Single {

  private Single() {
  }

  private static Single single = null;

  public static Single getInstance() {
    if (single == null) {
      single = new Single();
    }
    return single;
  }
}

饿汉式

public class Single {

  private Single() {
  }

  private static final Single single = new Single();

  public static Single getInstance() {
    return single;
  }
}

优点

  • 内存中只有一个实例,减少了内存开销
  • 避免了对资源的多重占用
  • 设置全局的访问点

缺点

  • 一般没有接口,难以扩展
  • 对于测试不利
  • 与单一职责原则有冲突

使用场景

  • 生成唯一序列号的环境
  • 整个项目需要一个共享访问点或共享数据
  • 创建一个对象需要消耗的资源过多
  • 需要定义大量的静态常量和静态方法

注意事项

  • 高并发情况注意线程同步问题

工厂模式

案例引入

女娲用八卦炉造人

具体代码

public class personFactory {

  public <T extends Person> T createPerson(Class<T> c) {
    Person person=null;
    try {
      person=(Person)Class.forName(c.getName()).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)person;
  }
}
public interface Person {

  void complexion();

  void talk();
}
public class black implements Person {

  @Override
  public void complexion() {
    System.out.println("黑种人");
  }

  @Override
  public void talk() {
    System.out.println("我是黑人");
  }
}

public class white implements Person {

  @Override
  public void complexion() {
    System.out.println("白种人");
  }

  @Override
  public void talk() {
    System.out.println("我是外国人");
  }
}

public class yellow implements Person {

  @Override
  public void complexion() {
    System.out.println("黄种人");
  }

  @Override
  public void talk() {
    System.out.println("我是黄种人");
  }
}
 personFactory personFactory = new personFactory();
    Person person1 = personFactory.createPerson(yellow.class);
    person1.complexion();
    person1.talk();
    Person person2 = personFactory.createPerson(white.class);
    person2.complexion();
    person2.talk();
    Person person3 = personFactory.createPerson(black.class);
    person3.complexion();
    person3.talk();

优点

  • 降低模块之间的耦合

使用场景

  • 是new的一个代替品
  • 需要灵活的,可扩展的框架

抽象工厂模式

案例引入

女娲造人不能只分为黄,黑,白吧,还得是男女对不对?

具体代码

public interface Person {

  void complexion();

  void talk();

  void sex();
}
public abstract class black implements Person {

  @Override
  public void complexion() {
    System.out.println("黑种人");
  }

  @Override
  public void talk() {
    System.out.println("我是黑人");
  }
}
public class FemaleBlack extends black {

  public void sex() {
    System.out.println("黑人女性");
  }
}
public interface personFactory {

  public Person createYellow();

  public Person createWhile();

  public Person createBlack();
}
public class MaleFactory implements personFactory {

  @Override
  public Person createYellow() {
    return null;
  }

  @Override
  public Person createWhile() {
    return null;
  }

  @Override
  public Person createBlack() {
    return new FemaleBlack();
  }
}
    MaleFactory maleFactory=new MaleFactory();
    Person black=maleFactory.createBlack();
    black.sex();

优点

  • 封装性
  • 约束变为非公开状态

缺点

  • 扩展困难

使用场景

一组对象都有相同的约束,则可以使用抽象工厂模式

模板方法模式

案例引入

制造车子,客户检验车的质量

具体代码

public abstract class Car {

  public abstract void start();

  public abstract void alarm();

  public abstract void stop();

  public void run() {
    this.start();
    this.alarm();
    this.stop();
  }
}
public class CarModel extends Car {

  @Override
  public void start() {
    System.out.println("启动");
  }

  @Override
  public void alarm() {
    System.out.println("鸣喇叭");
  }

  @Override
  public void stop() {
    System.out.println("停车");
  }

}
    Car car=new CarModel();
    car.run();

优点

  • 封装不变部分,扩展可变部分
  • 提取公共部分代码,便于维护
  • 行为又父类控制,子类实现

使用场景

  • 多个子类有共有的方法,基本逻辑相同

  • 重要的算法设计为模板方法,细节功能又子类实现

  • 相同的代码抽取到父类,通过钩子函数约束行为(如下)

扩展

public abstract class Car {

  public abstract boolean isAlarm();

  public abstract void start();

  public abstract void alarm();

  public abstract void stop();

  public void run() {
    this.start();
    if (this.isAlarm()) {
      this.alarm();
    }
    this.stop();
  }
}
public class CarModel extends Car {
public boolean alarmFlag=true;
  @Override
  public void start() {
    System.out.println("启动");
  }

  @Override
  public void alarm() {
    System.out.println("鸣喇叭");
  }

  @Override
  public void stop() {
    System.out.println("停车");
  }

  public boolean isAlarm() {
    return alarmFlag;
  }

  public void setAlarmFlag(boolean alarmFlag) {
    this.alarmFlag = alarmFlag;
  }
}

建造者模式

案例引入

造了车之后,测试的顺序可能不同,不一定是启动,鸣喇叭,停车,也可以是鸣喇叭,启动,停车等等,如果需求多了,我们可以定义一个建造者,你要啥循序都告诉建造者

具体代码

public abstract class Car {

  public ArrayList<String> sequence = new ArrayList<>();

  public abstract boolean isAlarm();

  public abstract void start();

  public abstract void alarm();

  public abstract void stop();

  public void run() {
    for (int i = 0; i < this.sequence.size(); i++) {
      String actionName = this.sequence.get(i);
      if (actionName.equalsIgnoreCase("start")) {
        this.start();
      } else if (actionName.equalsIgnoreCase("alarm")) {
        this.alarm();
      } else if (actionName.equalsIgnoreCase("stop")) {
        this.stop();
      }
    }
  }

  public void setSequence(ArrayList<String> sequence) {
    this.sequence = sequence;
  }
}
public class CarModel extends Car {
  @Override
  public void start() {
    System.out.println("启动");
  }

  @Override
  public void alarm() {
    System.out.println("鸣喇叭");
  }

  @Override
  public void stop() {
    System.out.println("停车");
  }
}
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("alarm");
    arrayList.add("start");
    arrayList.add("stop");
    car.setSequence(arrayList);
    car.run();

优点

  • 建造者独立
  • 便于控制细节
  • 封装线

使用场景

  • 相同的方法,不同的执行顺序
  • 多个部件,可以装配到一个对象中,但是产生的运行结果不相同
  • 产品类非常复杂

代理模式

案例引入

游戏代练(不提倡这种行为哟),明星和经纪人

具体代码

  • 动态代理
public interface Player {

  void login();

  void boss();

  void stop();
}

public class sPlayer implements Player {

  @Override
  public void login() {
    System.out.println("登陆账号");
  }

  @Override
  public void boss() {
    System.out.println("打boss");
  }

  @Override
  public void stop() {
    System.out.println("退出游戏");
  }
}
 Player sPlayer=new sPlayer();
    Player proxyPlayer = (Player) Proxy.newProxyInstance(test.class.getClassLoader(),
        sPlayer.class.getInterfaces(), new InvocationHandler() {
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("-");
            Object object=method.invoke(sPlayer, args);
            System.out.println("=");
            return object;
          }
        });
    proxyPlayer.login();
    proxyPlayer.boss();
    proxyPlayer.stop();

优点

  • 职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他飞奔职责的事务
  • 高扩展性
  • 智能化

使用场景

  • Spring的AOP

你可能感兴趣的:(设计模式之禅总结(持续更新))