简单介绍23种设计模式
| 创建型模式 | 工厂模式 抽象工厂模式 单例模式 建造者模式 原型模式 |
|---|---|
| 结构型模式 | 适配器模式 桥接模式 过滤器模式 组合模式 装饰其模式 外观模式 享元模式 代理模式 |
| 行为型模式 | 责任链模式 命令模式 解释其模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 空对象模式 策略模式 模版方法 访问者模式 |
工厂模式和抽象工厂
简单工厂
- 工厂类根据传入的参数,判断生产不同的实例对象。
- 简单工厂每新增一个新的实例类型时,都要修改工厂方法。会使工厂类越来越复杂。
- 违背了开闭原则(拓展开放,内容封闭)
class Animal {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}class Factory {public static Animal creatAnimal(String type) {Animal animal = null;switch (type) {case "cat":animal = new Cat();break;case "dog":animal = new Dog();break;default:}return animal;}}class Dog extends Animal {public Dog() {setName("dog");}}class Cat extends Animal {public Cat() {setName("cat");}}public class SimpleFactoryDesign {public static void main(String[] args) {Animal animal = Factory.creatAnimal("cat");System.out.println(animal.getName());animal = Factory.creatAnimal("dog");System.out.println(animal.getName());}}
工厂方法
- 将工厂类的创建延迟到子类(解决了增加子类直接修改工厂方法)
class Animal {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}class Dog extends Animal {public Dog() {setName("dog");}}class Cat extends Animal {public Cat() {setName("cat");}}abstract class AbstractFactory {abstract Animal creatAnimal();public void getName() {System.out.println(creatAnimal().getName());}}class DogFactory extends AbstractFactory {@OverrideAnimal creatAnimal() {return new Dog();}}class CatFactory extends AbstractFactory {@OverrideAnimal creatAnimal() {return new Cat();}}public class FactoryMethodDesign {public static void main(String[] args) {AbstractFactory catFactory = new CatFactory();AbstractFactory dogFactory = new DogFactory();catFactory.getName();dogFactory.getName();}}
抽象工厂
- 工厂生产多类产品
- 新增产品,要创建对应的工厂
abstract class Animal {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}abstract class Plant {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}}class Dog extends Animal {public Dog() {setName("dog");}}class Cat extends Animal {public Cat() {setName("cat");}}class Pine extends Plant {public Pine() {setName("pine");}}class Cypress extends Plant {public Cypress() {setName("cypress");}}abstract class Factory {abstract Animal creatAnimal();abstract Plant creatPlant();}class Factory1 extends Factory {@OverrideAnimal creatAnimal() {return new Dog();}@OverridePlant creatPlant() {return new Pine();}}class Factory2 extends Factory {@OverrideAnimal creatAnimal() {return new Cat();}@OverridePlant creatPlant() {return new Cypress();}}public class AbstractFactoryDesign {public static void main(String[] args) {Factory factory1 = new Factory1();System.out.println(factory1.creatAnimal().getName());System.out.println(factory1.creatPlant().getName());Factory factory2 = new Factory2();System.out.println(factory2.creatAnimal().getName());System.out.println(factory2.creatPlant().getName());}}
总结
- 首先从简单工厂进化到工厂方法,是因为工厂方法弥补了简单工厂对修改开放的弊端,即简单工厂违背了开闭原则。
- 从工厂方法进化到抽象工厂,是因为抽象工厂弥补了工厂方法只能创造一个系列的产品的弊端。
单例模式
懒汉式
- 比较懒嘛,所以用的时候才创建实例对象
public class LazySingleton {private static LazySingleton singleton;private LazySingleton() {}public static LazySingleton getInstance() {if (singleton == null) {synchronized (LazySingleton.class) {if (singleton == null) {singleton = new LazySingleton();}}}return singleton;}}
饿汉式
- 饿汉,等不及了,所以是提前创建对象
public class HungrySingleton {private HungrySingleton singleton = new HungrySingleton();private HungrySingleton() {}public HungrySingleton getSingleton(){return singleton;}}
静态内部类
public class InnerClassSingleton {private InnerClassSingleton() {}private static class Inner {private static final InnerClassSingleton singleton = new InnerClassSingleton();}public static InnerClassSingleton getInstance() {return Inner.singleton;}}
枚举
- 枚举默认构造方法私有
public enum SingletonEnum {ONE,TWO,THREE;public static SingletonEnum getOne(){return ONE;}public static SingletonEnum getTwo(){return TWO;}public static SingletonEnum getThree(){return THREE;}}
建造者模式
将一个复杂的对象的构建与它的表示分离,使
得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
经典模式
@Dataclass Computer {private String cup;private String gpu;private String disk;private String ram;}@Dataabstract class ComputerBuilder {abstract void setCup();abstract void setGpu();abstract void setDisk();abstract void setRam();abstract Computer getComputer();}class HigherComputerBuilder extends ComputerBuilder {private Computer computer;public HigherComputerBuilder() {this.computer = new Computer();}@Overridevoid setCup() {computer.setCup("8G");}@Overridevoid setGpu() {computer.setGpu("4G");}@Overridevoid setDisk() {computer.setDisk("1T");}@Overridevoid setRam() {computer.setRam("16G");}@OverrideComputer getComputer() {return computer;}}class TowerComputerBuilder extends ComputerBuilder {private Computer computer;public TowerComputerBuilder() {this.computer = new Computer();}@Overridevoid setCup() {computer.setCup("4G");}@Overridevoid setGpu() {computer.setGpu("2G");}@Overridevoid setDisk() {computer.setDisk("500G");}@Overridevoid setRam() {computer.setRam("8G");}@OverrideComputer getComputer() {return computer;}}class Director {private ComputerBuilder computerBuilder;public Director(ComputerBuilder computerBuilder) {this.computerBuilder = computerBuilder;}public Computer createComputerBuilder() {computerBuilder.setCup();computerBuilder.setDisk();computerBuilder.setGpu();computerBuilder.setRam();return computerBuilder.getComputer();}}public class Main {public static void main(String[] args) {Computer computer = new Director(new HigherComputerBuilder()).createComputerBuilder();System.out.println("高配:" + computer);computer = new Director(new TowerComputerBuilder()).createComputerBuilder();System.out.println("低配:" + computer);}}
变种模式
@Dataclass Person {private String name;private String gender;private int age;private double money;private String house;}class PersonBuilder {private String name;private String gender;private int age;private double money;private String house;public PersonBuilder(String name, String gender) {this.name = name;this.gender = gender;}public PersonBuilder age(int age) {this.age = age;return this;}public PersonBuilder money(double money) {this.money = money;return this;}public PersonBuilder house(String house) {this.house = house;return this;}public Person build() {Person person = new Person();person.setName(name);person.setAge(age);person.setGender(gender);person.setMoney(money);person.setHouse(house);return person;}}public class VarietyBuilder {public static void main(String[] args) {System.out.println(new PersonBuilder("小明", "man").age(11).house("big").money(1111111111).build());}}
原型模式
对象拷贝
- 浅拷贝
只复制基本类型,非基本类型需要自定义实现 - 深拷贝
所有对象
代码实现
@Dataclass Persion implements Cloneable {private String name;private int age;private HashMap<String, String> propertis;@Overrideprotected Persion clone() throws CloneNotSupportedException {Persion persion = (Persion) super.clone();//非基本类型自定义拷贝persion.propertis = (HashMap<String, String>) this.propertis.clone();return persion;}}public class Prototype {public static void main(String[] args) throws CloneNotSupportedException {Persion persion = new Persion();persion.setAge(11);persion.setName("小明");HashMap<String, String> propertis = new HashMap<>();propertis.put("money", "20亿");propertis.put("gender", "man");persion.setPropertis(propertis);Persion persion1 = persion.clone();System.out.println(persion);System.out.println(persion1);System.out.println(persion.getPropertis() == persion1.getPropertis());}}
结果:
我是构造方法Persion(name=小明, age=11, propertis={money=20亿, gender=man})Persion(name=小明, age=11, propertis={money=20亿, gender=man})false
总结
- clone方法创建对象不会调用其构造方法。
- 被clone对象要实现Cloneable接口
- 默认super.clone只能复制基本类型,非基本类型需要自定义实现
- 原型模式可以用来快速创建复杂对象
适配器模式
类适配器
interface Player {void action();}interface Mp4 {void play();}class ExpensiveMp4 implements Mp4 {@Overridepublic void play() {System.out.println("play mp4");}}public class PlayerAdapter extends ExpensiveMp4 implements Player {@Overridepublic void action() {play();}}
接口适配器
interface Player {void action();}interface Mp4 {void play();}class ExpensiveMp4 implements Mp4 {@Overridepublic void play() {System.out.println("play mp4");}}public class PlayerAdapter implements Player {private Mp4 mp4;public PlayerAdapter(Mp4 mp4) {this.mp4 = mp4;}@Overridepublic void action() {mp4.play();}}
总结
- 提高代码复用
- 灵活性非常好
- 适配器其实是对目标类/接口的包装,实际工作只有目标类/接口
