简单介绍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 {
@Override
Animal creatAnimal() {
return new Dog();
}
}
class CatFactory extends AbstractFactory {
@Override
Animal 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 {
@Override
Animal creatAnimal() {
return new Dog();
}
@Override
Plant creatPlant() {
return new Pine();
}
}
class Factory2 extends Factory {
@Override
Animal creatAnimal() {
return new Cat();
}
@Override
Plant 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;
}
}
建造者模式
将一个复杂的对象的构建与它的表示分离,使
得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
经典模式
@Data
class Computer {
private String cup;
private String gpu;
private String disk;
private String ram;
}
@Data
abstract 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();
}
@Override
void setCup() {
computer.setCup("8G");
}
@Override
void setGpu() {
computer.setGpu("4G");
}
@Override
void setDisk() {
computer.setDisk("1T");
}
@Override
void setRam() {
computer.setRam("16G");
}
@Override
Computer getComputer() {
return computer;
}
}
class TowerComputerBuilder extends ComputerBuilder {
private Computer computer;
public TowerComputerBuilder() {
this.computer = new Computer();
}
@Override
void setCup() {
computer.setCup("4G");
}
@Override
void setGpu() {
computer.setGpu("2G");
}
@Override
void setDisk() {
computer.setDisk("500G");
}
@Override
void setRam() {
computer.setRam("8G");
}
@Override
Computer 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);
}
}
变种模式
@Data
class 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());
}
}
原型模式
对象拷贝
- 浅拷贝
只复制基本类型,非基本类型需要自定义实现 - 深拷贝
所有对象
代码实现
@Data
class Persion implements Cloneable {
private String name;
private int age;
private HashMap<String, String> propertis;
@Override
protected 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 {
@Override
public void play() {
System.out.println("play mp4");
}
}
public class PlayerAdapter extends ExpensiveMp4 implements Player {
@Override
public void action() {
play();
}
}
接口适配器
interface Player {
void action();
}
interface Mp4 {
void play();
}
class ExpensiveMp4 implements Mp4 {
@Override
public void play() {
System.out.println("play mp4");
}
}
public class PlayerAdapter implements Player {
private Mp4 mp4;
public PlayerAdapter(Mp4 mp4) {
this.mp4 = mp4;
}
@Override
public void action() {
mp4.play();
}
}
总结
- 提高代码复用
- 灵活性非常好
- 适配器其实是对目标类/接口的包装,实际工作只有目标类/接口