简单介绍23种设计模式

创建型模式 工厂模式
抽象工厂模式
单例模式
建造者模式
原型模式
结构型模式 适配器模式
桥接模式
过滤器模式
组合模式
装饰其模式
外观模式
享元模式
代理模式
行为型模式 责任链模式
命令模式
解释其模式
迭代器模式
中介者模式
备忘录模式
观察者模式
状态模式
空对象模式
策略模式
模版方法
访问者模式

工厂模式和抽象工厂

简单工厂

  • 工厂类根据传入的参数,判断生产不同的实例对象。
  • 简单工厂每新增一个新的实例类型时,都要修改工厂方法。会使工厂类越来越复杂。
  • 违背了开闭原则(拓展开放,内容封闭)
  1. class Animal {
  2. private String name;
  3. public String getName() {
  4. return name;
  5. }
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. }
  10. class Factory {
  11. public static Animal creatAnimal(String type) {
  12. Animal animal = null;
  13. switch (type) {
  14. case "cat":
  15. animal = new Cat();
  16. break;
  17. case "dog":
  18. animal = new Dog();
  19. break;
  20. default:
  21. }
  22. return animal;
  23. }
  24. }
  25. class Dog extends Animal {
  26. public Dog() {
  27. setName("dog");
  28. }
  29. }
  30. class Cat extends Animal {
  31. public Cat() {
  32. setName("cat");
  33. }
  34. }
  35. public class SimpleFactoryDesign {
  36. public static void main(String[] args) {
  37. Animal animal = Factory.creatAnimal("cat");
  38. System.out.println(animal.getName());
  39. animal = Factory.creatAnimal("dog");
  40. System.out.println(animal.getName());
  41. }
  42. }

工厂方法

  • 将工厂类的创建延迟到子类(解决了增加子类直接修改工厂方法)
  1. class Animal {
  2. private String name;
  3. public String getName() {
  4. return name;
  5. }
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. }
  10. class Dog extends Animal {
  11. public Dog() {
  12. setName("dog");
  13. }
  14. }
  15. class Cat extends Animal {
  16. public Cat() {
  17. setName("cat");
  18. }
  19. }
  20. abstract class AbstractFactory {
  21. abstract Animal creatAnimal();
  22. public void getName() {
  23. System.out.println(creatAnimal().getName());
  24. }
  25. }
  26. class DogFactory extends AbstractFactory {
  27. @Override
  28. Animal creatAnimal() {
  29. return new Dog();
  30. }
  31. }
  32. class CatFactory extends AbstractFactory {
  33. @Override
  34. Animal creatAnimal() {
  35. return new Cat();
  36. }
  37. }
  38. public class FactoryMethodDesign {
  39. public static void main(String[] args) {
  40. AbstractFactory catFactory = new CatFactory();
  41. AbstractFactory dogFactory = new DogFactory();
  42. catFactory.getName();
  43. dogFactory.getName();
  44. }
  45. }

抽象工厂

  • 工厂生产多类产品
  • 新增产品,要创建对应的工厂
  1. abstract class Animal {
  2. private String name;
  3. public String getName() {
  4. return name;
  5. }
  6. public void setName(String name) {
  7. this.name = name;
  8. }
  9. }
  10. abstract class Plant {
  11. private String name;
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. }
  19. class Dog extends Animal {
  20. public Dog() {
  21. setName("dog");
  22. }
  23. }
  24. class Cat extends Animal {
  25. public Cat() {
  26. setName("cat");
  27. }
  28. }
  29. class Pine extends Plant {
  30. public Pine() {
  31. setName("pine");
  32. }
  33. }
  34. class Cypress extends Plant {
  35. public Cypress() {
  36. setName("cypress");
  37. }
  38. }
  39. abstract class Factory {
  40. abstract Animal creatAnimal();
  41. abstract Plant creatPlant();
  42. }
  43. class Factory1 extends Factory {
  44. @Override
  45. Animal creatAnimal() {
  46. return new Dog();
  47. }
  48. @Override
  49. Plant creatPlant() {
  50. return new Pine();
  51. }
  52. }
  53. class Factory2 extends Factory {
  54. @Override
  55. Animal creatAnimal() {
  56. return new Cat();
  57. }
  58. @Override
  59. Plant creatPlant() {
  60. return new Cypress();
  61. }
  62. }
  63. public class AbstractFactoryDesign {
  64. public static void main(String[] args) {
  65. Factory factory1 = new Factory1();
  66. System.out.println(factory1.creatAnimal().getName());
  67. System.out.println(factory1.creatPlant().getName());
  68. Factory factory2 = new Factory2();
  69. System.out.println(factory2.creatAnimal().getName());
  70. System.out.println(factory2.creatPlant().getName());
  71. }
  72. }

总结

  • 首先从简单工厂进化到工厂方法,是因为工厂方法弥补了简单工厂对修改开放的弊端,即简单工厂违背了开闭原则。
  • 从工厂方法进化到抽象工厂,是因为抽象工厂弥补了工厂方法只能创造一个系列的产品的弊端。

单例模式

懒汉式

  • 比较懒嘛,所以用的时候才创建实例对象
  1. public class LazySingleton {
  2. private static LazySingleton singleton;
  3. private LazySingleton() {
  4. }
  5. public static LazySingleton getInstance() {
  6. if (singleton == null) {
  7. synchronized (LazySingleton.class) {
  8. if (singleton == null) {
  9. singleton = new LazySingleton();
  10. }
  11. }
  12. }
  13. return singleton;
  14. }
  15. }

饿汉式

  • 饿汉,等不及了,所以是提前创建对象
  1. public class HungrySingleton {
  2. private HungrySingleton singleton = new HungrySingleton();
  3. private HungrySingleton() {
  4. }
  5. public HungrySingleton getSingleton(){
  6. return singleton;
  7. }
  8. }

静态内部类

  1. public class InnerClassSingleton {
  2. private InnerClassSingleton() {
  3. }
  4. private static class Inner {
  5. private static final InnerClassSingleton singleton = new InnerClassSingleton();
  6. }
  7. public static InnerClassSingleton getInstance() {
  8. return Inner.singleton;
  9. }
  10. }

枚举

  • 枚举默认构造方法私有
  1. public enum SingletonEnum {
  2. ONE,
  3. TWO,
  4. THREE;
  5. public static SingletonEnum getOne(){
  6. return ONE;
  7. }
  8. public static SingletonEnum getTwo(){
  9. return TWO;
  10. }
  11. public static SingletonEnum getThree(){
  12. return THREE;
  13. }
  14. }

建造者模式

将一个复杂的对象的构建与它的表示分离,使

得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。

经典模式

  1. @Data
  2. class Computer {
  3. private String cup;
  4. private String gpu;
  5. private String disk;
  6. private String ram;
  7. }
  8. @Data
  9. abstract class ComputerBuilder {
  10. abstract void setCup();
  11. abstract void setGpu();
  12. abstract void setDisk();
  13. abstract void setRam();
  14. abstract Computer getComputer();
  15. }
  16. class HigherComputerBuilder extends ComputerBuilder {
  17. private Computer computer;
  18. public HigherComputerBuilder() {
  19. this.computer = new Computer();
  20. }
  21. @Override
  22. void setCup() {
  23. computer.setCup("8G");
  24. }
  25. @Override
  26. void setGpu() {
  27. computer.setGpu("4G");
  28. }
  29. @Override
  30. void setDisk() {
  31. computer.setDisk("1T");
  32. }
  33. @Override
  34. void setRam() {
  35. computer.setRam("16G");
  36. }
  37. @Override
  38. Computer getComputer() {
  39. return computer;
  40. }
  41. }
  42. class TowerComputerBuilder extends ComputerBuilder {
  43. private Computer computer;
  44. public TowerComputerBuilder() {
  45. this.computer = new Computer();
  46. }
  47. @Override
  48. void setCup() {
  49. computer.setCup("4G");
  50. }
  51. @Override
  52. void setGpu() {
  53. computer.setGpu("2G");
  54. }
  55. @Override
  56. void setDisk() {
  57. computer.setDisk("500G");
  58. }
  59. @Override
  60. void setRam() {
  61. computer.setRam("8G");
  62. }
  63. @Override
  64. Computer getComputer() {
  65. return computer;
  66. }
  67. }
  68. class Director {
  69. private ComputerBuilder computerBuilder;
  70. public Director(ComputerBuilder computerBuilder) {
  71. this.computerBuilder = computerBuilder;
  72. }
  73. public Computer createComputerBuilder() {
  74. computerBuilder.setCup();
  75. computerBuilder.setDisk();
  76. computerBuilder.setGpu();
  77. computerBuilder.setRam();
  78. return computerBuilder.getComputer();
  79. }
  80. }
  81. public class Main {
  82. public static void main(String[] args) {
  83. Computer computer = new Director(new HigherComputerBuilder()).createComputerBuilder();
  84. System.out.println("高配:" + computer);
  85. computer = new Director(new TowerComputerBuilder()).createComputerBuilder();
  86. System.out.println("低配:" + computer);
  87. }
  88. }

变种模式

  1. @Data
  2. class Person {
  3. private String name;
  4. private String gender;
  5. private int age;
  6. private double money;
  7. private String house;
  8. }
  9. class PersonBuilder {
  10. private String name;
  11. private String gender;
  12. private int age;
  13. private double money;
  14. private String house;
  15. public PersonBuilder(String name, String gender) {
  16. this.name = name;
  17. this.gender = gender;
  18. }
  19. public PersonBuilder age(int age) {
  20. this.age = age;
  21. return this;
  22. }
  23. public PersonBuilder money(double money) {
  24. this.money = money;
  25. return this;
  26. }
  27. public PersonBuilder house(String house) {
  28. this.house = house;
  29. return this;
  30. }
  31. public Person build() {
  32. Person person = new Person();
  33. person.setName(name);
  34. person.setAge(age);
  35. person.setGender(gender);
  36. person.setMoney(money);
  37. person.setHouse(house);
  38. return person;
  39. }
  40. }
  41. public class VarietyBuilder {
  42. public static void main(String[] args) {
  43. System.out.println(new PersonBuilder("小明", "man")
  44. .age(11).house("big")
  45. .money(1111111111).build());
  46. }
  47. }

原型模式

对象拷贝

  • 浅拷贝
    只复制基本类型,非基本类型需要自定义实现
  • 深拷贝
    所有对象

代码实现

  1. @Data
  2. class Persion implements Cloneable {
  3. private String name;
  4. private int age;
  5. private HashMap<String, String> propertis;
  6. @Override
  7. protected Persion clone() throws CloneNotSupportedException {
  8. Persion persion = (Persion) super.clone();
  9. //非基本类型自定义拷贝
  10. persion.propertis = (HashMap<String, String>) this.propertis.clone();
  11. return persion;
  12. }
  13. }
  14. public class Prototype {
  15. public static void main(String[] args) throws CloneNotSupportedException {
  16. Persion persion = new Persion();
  17. persion.setAge(11);
  18. persion.setName("小明");
  19. HashMap<String, String> propertis = new HashMap<>();
  20. propertis.put("money", "20亿");
  21. propertis.put("gender", "man");
  22. persion.setPropertis(propertis);
  23. Persion persion1 = persion.clone();
  24. System.out.println(persion);
  25. System.out.println(persion1);
  26. System.out.println(persion.getPropertis() == persion1.getPropertis());
  27. }
  28. }

结果:

  1. 我是构造方法
  2. Persion(name=小明, age=11, propertis={money=20亿, gender=man})
  3. Persion(name=小明, age=11, propertis={money=20亿, gender=man})
  4. false

总结

  • clone方法创建对象不会调用其构造方法。
  • 被clone对象要实现Cloneable接口
  • 默认super.clone只能复制基本类型,非基本类型需要自定义实现
  • 原型模式可以用来快速创建复杂对象

适配器模式

类适配器

  1. interface Player {
  2. void action();
  3. }
  4. interface Mp4 {
  5. void play();
  6. }
  7. class ExpensiveMp4 implements Mp4 {
  8. @Override
  9. public void play() {
  10. System.out.println("play mp4");
  11. }
  12. }
  13. public class PlayerAdapter extends ExpensiveMp4 implements Player {
  14. @Override
  15. public void action() {
  16. play();
  17. }
  18. }

接口适配器

  1. interface Player {
  2. void action();
  3. }
  4. interface Mp4 {
  5. void play();
  6. }
  7. class ExpensiveMp4 implements Mp4 {
  8. @Override
  9. public void play() {
  10. System.out.println("play mp4");
  11. }
  12. }
  13. public class PlayerAdapter implements Player {
  14. private Mp4 mp4;
  15. public PlayerAdapter(Mp4 mp4) {
  16. this.mp4 = mp4;
  17. }
  18. @Override
  19. public void action() {
  20. mp4.play();
  21. }
  22. }

总结

  • 提高代码复用
  • 灵活性非常好
  • 适配器其实是对目标类/接口的包装,实际工作只有目标类/接口