单例模式

饿汉式
1
2
3
4
5
6
7
8
9
public class SingleModeHunger {
private SingleModeHunger() {}

private static SingleModeHunger instance = new SingleModeHunger();

public static SingleModeHunger getInsatce() {
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public class SingleModeHungerStaticBlock { // 通过静态代码块
private SingleModeHungerStaticBlock() {}

private static SingleModeHungerStaticBlock singleModeHungerStaticBlock;

static {
singleModeHungerStaticBlock = new SingleModeHungerStaticBlock();
}
public static SingleModeHungerStaticBlock getInsatce() {
return singleModeHungerStaticBlock;
}
}

优点:保证线程同步,单实例

缺点:资源浪费,如果不使用也会创建对象

懒汉式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//线程不安全
public class SingleModeLazy {

private static SingleModeLazy singleModeLazy;

private SingleModeLazy() {
}
public static SingleModeLazy getInstance() {
if (singleModeLazy == null) {
singleModeLazy = new SingleModeLazy();
}
return singleModeLazy;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SingleModeLazySafeThread { // 推荐使用,线程安全+懒加载;序列化会出问题
private SingleModeLazySafeThread() {
}
// 必须 + volatile
private static volatile SingleModeLazySafeThread singleModeLazySafeThread;

public static SingleModeLazySafeThread getInstance() {
if (singleModeLazySafeThread == null) {
synchronized (SingleModeLazySafeThread.class) {
if (singleModeLazySafeThread == null) {
singleModeLazySafeThread = new SingleModeLazySafeThread();
}
}
}
return singleModeLazySafeThread;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 静态内部类
public class SingleLazySafeThreadStaticInClass {
private SingleLazySafeThreadStaticInClass() {
}

private static class Inner {
private static SingleLazySafeThreadStaticInClass instance = new SingleLazySafeThreadStaticInClass();
}

public static SingleLazySafeThreadStaticInClass getInstance() {
return Inner.instance;
}
}
1
2
3
4
5
6
7
// 枚举
public enum SingletonEnum {
INSTANCE;
public void singletonEnumMethod() {
System.out.println("singleton");
}
}

JDK中的单例

image-20230530103655370

工厂模式

简单工厂

image-20230530141859310

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Tea
public abstract class Tea {
private String name;
abstract void prepare();

public void make() {
System.out.println(name + ": 制造中");
}
public void pkg() {
System.out.println(name + ": 打包中");
}

public void setName(String name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
AppleTea, 其他水果类似
public class AppleTea extends Tea{
public AppleTea() {super.setName("🍎");}
@Override
void prepare() {
System.out.println("🍎原材料准备中...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
SimpleFactory
public class SimpleFactory {
public static Tea createTea(String teaType) {
if (teaType.equals("菠萝")) {
return new PineAppleTea();
} else if (teaType.equals("苹果")) {
return new AppleTea();
} else if (teaType.equals("橘子")) {
return new OrangeTea();
}
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OrderTea
public class OrderTea {
public void order(String teaType) {
Tea tea = SimpleFactory.createTea(teaType);
assert tea != null;
tea.prepare();
tea.make();
tea.pkg();
}
}

Test
public class Test { // 对与不同teaType创建不同Tea对象
public static void main(String[] args) {
OrderTea orderTea = new OrderTea();
orderTea.order("橘子");
}
}
工厂方法

上面简单工厂负责创建对象的SimpleFactory替换成对应的xxOrderTea,由某个特定的xxOrderTea负责实例对应的对象

image-20230530211120381

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public abstract class Tea {
private String name;
abstract void prepare();

public void make() {
System.out.println(name + ": 制造中");
}
public void pkg() {
System.out.println(name + ": 打包中");
}

public void setName(String name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AppleTea extends Tea {
@Override
void prepare() {
System.out.println("🍎原材料准备中...");
}
}
public class OrangeTea extends Tea {
@Override
public void prepare() {
System.out.println("🍊原材料准备中...");
}
}
public class PineAppleTea extends Tea {
@Override
protected void prepare() {
System.out.println("🍍原材料准备中...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ChengduOrderTea extends OrderTea{
private static Tea tea = null;

public ChengduOrderTea(String teaType) {
order(teaType);
}

public Tea createTea(String teaType) {
if (teaType.equals("菠萝")) {
PineAppleTea pineAppleTea = new PineAppleTea();
pineAppleTea.setName("成都🍍");
tea = pineAppleTea;
} else if (teaType.equals("苹果")) {
AppleTea appleTea = new AppleTea();
appleTea.setName("成都🍎");
tea = appleTea;
} else if (teaType.equals("橘子")) {
OrangeTea orangeTea = new OrangeTea();
orangeTea.setName("成都🍊");
tea = orangeTea;
}
return tea;
}
}
1
2
3
4
5
6
7
8
9
public abstract class OrderTea {
public abstract Tea createTea(String teaType);
public void order(String teaType) {
Tea tea = createTea(teaType);
tea.prepare();
tea.make();
tea.pkg();
}
}
抽象工厂

image-20230530213358001

image-20230530215257136

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public interface AbsFactory {
Tea createTea(String teaType);
}

public class ChengDuFactory implements AbsFactory{
private Tea tea;

public Tea createTea(String teaType) {
if (teaType.equals("菠萝")) {
PineAppleTea pineAppleTea = new PineAppleTea();
pineAppleTea.setName("成都🍍");
tea = pineAppleTea;
} else if (teaType.equals("苹果")) {
AppleTea appleTea = new AppleTea();
appleTea.setName("成都🍎");
tea = appleTea;
} else if (teaType.equals("橘子")) {
OrangeTea orangeTea = new OrangeTea();
orangeTea.setName("成都🍊");
tea = orangeTea;
}
return tea;
}
}

public class OrderTea {

private AbsFactory absFactory;

public OrderTea(AbsFactory absFactory) {
this.absFactory = absFactory;
}

public void order(String teaType) {
Tea tea = absFactory.createTea(teaType);
tea.prepare();
tea.make();
tea.pkg();
}
}

// 其他上面有,不写了

再JDK中的实现,Calendar使用了简单工厂模式,Calendar实例化时,如果CalendarProvider为null的话,会走以下代码,根据caltype判断需要实例话的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Calendar calendar = Calendar.getInstance();
-----------------------------------------------------------------------------
Calendar cal = null;

if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}

原型模式

对对象数据进行克隆

1、浅拷贝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Sheep implements Cloneable {

private String name;
private int age;
private String color;

@Override
protected Sheep clone() throws CloneNotSupportedException {
return (Sheep) super.clone();
}
}

public class Clint {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep("black", 10, "red");
Sheep sheep2 = sheep.clone();
Sheep sheep3 = sheep.clone();
Sheep sheep4 = sheep.clone();
System.out.println(sheep);
System.out.println(sheep2);
System.out.println(sheep3);
System.out.println(sheep4);
}
}
输出👇
Sheep(name=black, age=10, color=red)
Sheep(name=black, age=10, color=red)
Sheep(name=black, age=10, color=red)
Sheep(name=black, age=10, color=red)

Spring源码中,对Bean的scope有一种选项为prototype;

1
<bean id="user" class="org.example.pojo.User" scope="prototype"/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void t4() {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("user.xml");
Object user1 = classPathXmlApplicationContext.getBean("user");
Object user2 = classPathXmlApplicationContext.getBean("user");
System.out.println(user1);
System.out.println(user2);
System.out.println(user1 == user2);
}

输出👇
User{uname='null', age=0, jbo='null'}
User{uname='null', age=0, jbo='null'}
false

image-20230531181452557

image-20230531181759453

image-20230531182131202

image-20230531182406698

2、深拷贝

1、通过clone

2、通过序列化

1、通过clone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 自己引用自己会导致空指针,可用序列化替换;并且序列化可扩展性更强,添加其他需对象属性无需再手动修改代码。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sheep implements Cloneable {
private String name;
private int age;
private ChildSheep child;

@Override
protected Sheep clone() throws CloneNotSupportedException {
Sheep pSheep = (Sheep) super.clone();
ChildSheep childSheep = pSheep.getChild().clone();
pSheep.setChild(childSheep);
return pSheep;
}
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChildSheep implements Cloneable{
private String name;
private int age;

@Override
protected ChildSheep clone() throws CloneNotSupportedException {
return (ChildSheep) super.clone();
}
}

public class Clint {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep("parent", 29, null);
ChildSheep child = new ChildSheep("child", 10);
sheep.setChild(child);

Sheep clone = sheep.clone();
Sheep clone2 = sheep.clone();
System.out.println(clone);
System.out.println(clone2);
System.out.println(clone == clone2);
System.out.println(clone.getChild() == clone2.getChild());
}
}

Sheep(name=parent, age=29, child=ChildSheep(name=child, age=10))
Sheep(name=parent, age=29, child=ChildSheep(name=child, age=10))
false
false

2、通过序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChildSheep implements Serializable {
private String name;
private int age;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Sheep implements Cloneable, Serializable {
private String name;
private int age;
private ChildSheep child;

@Override
protected Sheep clone() throws CloneNotSupportedException {
ObjectInputStream ois = null;
ByteArrayInputStream bis = null;
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;

try {
// 写出
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(this);

// 写入
bis = new ByteArrayInputStream(baos.toByteArray());
ois = new ObjectInputStream(bis);
return (Sheep) ois.readObject();
} catch (Exception e) {
return null;
} finally {
try {
if (bis != null) bis.close();
if (ois != null) ois.close();
if (baos != null) baos.close();
if (oos != null) oos.close();
} catch (IOException ignored) {}
}
}
}
// sheep的child类型是自己或者ChildSheep都行
public class Clint {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep("parent", 29, null);
ChildSheep child = new ChildSheep("child", 10);
sheep.setChild(child);

Sheep clone = sheep.clone();
Sheep clone2 = sheep.clone();
System.out.println(clone);
System.out.println(clone2);
System.out.println(clone == clone2);
System.out.println(clone.getChild() == clone2.getChild());
}
}

Sheep(name=parent, age=29, child=ChildSheep(name=child, age=10))
Sheep(name=parent, age=29, child=ChildSheep(name=child, age=10))
false
false

建造者模式

如果一个对象的创建很复杂,需要很多步骤(差异性大),则可以考虑建造者而不是工厂,工厂是对象差异性不大。

四个角色: Product(产品角色)、Builder(抽象建造者)、ConcreteBulder(具体建造者)、Director(指挥者)

image-20230531211401233

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
public abstract class FruitJellyBuilder {
FruitJelly fruitJelly = new FruitJelly();
// 准备原材料
public abstract void prepareMaterials();
// 开始制作
public abstract void make();
// 打包
public abstract FruitJelly build();
}

public class AppleFruitJellyBuilder extends FruitJellyBuilder{

@Override
public void prepareMaterials() {
System.out.println("准备🍎果冻原材料...");
}

@Override
public void make() {
System.out.println("制作🍎果冻");
}

@Override
public FruitJelly build() {
fruitJelly.setColor("red");
fruitJelly.setName("🍎");
return fruitJelly;
}
}

public class OrangeFruitJellyBuilder extends FruitJellyBuilder {
@Override
public void prepareMaterials() {
System.out.println("准备🍊果冻原材料...");
}

@Override
public void make() {
System.out.println("制作🍊果冻");
}

@Override
public FruitJelly build() {
fruitJelly.setColor("orange");
fruitJelly.setName("🍊");
return fruitJelly;
}
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public class FruitJelly {
private String name;
private String color;
}

@NoArgsConstructor
public class FruiteJellyDirector {
private FruitJellyBuilder fruitJellyBuilder;

public void setFruitJellyBuilder(FruitJellyBuilder fruitJellyBuilder) {
this.fruitJellyBuilder = fruitJellyBuilder;
}

public FruiteJellyDirector(FruitJellyBuilder fruitJellyBuilder) {
this.fruitJellyBuilder = fruitJellyBuilder;
}

public FruitJelly getProduct() {
fruitJellyBuilder.prepareMaterials();
fruitJellyBuilder.make();
return fruitJellyBuilder.build();
}
}

public class Client {
public static void main(String[] args) {
AppleFruitJellyBuilder appleFruitJellyBuilder = new AppleFruitJellyBuilder();
OrangeFruitJellyBuilder orangeFruitJellyBuilder = new OrangeFruitJellyBuilder();
FruiteJellyDirector fruiteJellyDirector = new FruiteJellyDirector();
fruiteJellyDirector.setFruitJellyBuilder(appleFruitJellyBuilder);
System.out.println(fruiteJellyDirector.getProduct());
fruiteJellyDirector.setFruitJellyBuilder(orangeFruitJellyBuilder);
System.out.println(fruiteJellyDirector.getProduct());
}
}

输出👇
准备🍎果冻原材料...
制作🍎果冻
FruitJelly(name=🍎, color=red)
准备🍊果冻原材料...
制作🍊果冻
FruitJelly(name=🍊, color=orange)

JDK中的建造者StringBuilder,其中Appendable类似Bulder,StringBuilder是具体的Builder

1
StringBuilder stringBuilder = new StringBuilder();

image-20230531223336490

image-20230531223357299

image-20230531223414705

适配器模式

1、类适配器

image-20230601103001591

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Phone {

public void charging(Voltage5V v) {
int i = v.change5V();
System.out.println("开始充电: " + i + "V");
}
}

public interface Voltage5V {
int change5V();
}

public class Voltage5VAdapter extends Voltage220V implements Voltage5V{
@Override
public int change5V() {
return Voltage220V.Out220V() / 44;
}
}

public class Voltage220V {
public static int Out220V() {
System.out.println("输出22V");
return 220;
}
}
2、对象适配器

image-20230601103440943

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Client {
public static void main(String[] args) {
Voltage5VAdapter voltage5VAdapter = new Voltage5VAdapter(new Voltage220V());
Phone phone = new Phone();
phone.charging(voltage5VAdapter);
}
}

public class Phone {

public void charging(Voltage5V v) {
int i = v.change5V();
System.out.println("开始充电: " + i + "V");
}
}

public interface Voltage5V {
int change5V();
}

public class Voltage5VAdapter implements Voltage5V {
private Voltage220V voltage220V;

public Voltage5VAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}

@Override
public int change5V() {
return voltage220V.Out220V() / 44;
}
}

public class Voltage220V {
public int Out220V() {
System.out.println("输出22V");
return 220;
}
}
3、接口适配器

image-20230601112744901

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Client {
public static void main(String[] args) {
XXAdapter xxAdapter = new XXAdapter() {
@Override
public void op2() {
System.out.println("接口适配器");
}
};

xxAdapter.op2();
}
}

public abstract class XXAdapter implements XXAdapterInterface {
@Override
public void op1() {

}

@Override
public void op2() {

}

@Override
public void op3() {

}
}

public interface XXAdapterInterface {
void op1();
void op2();
void op3();
}

SpringMVC中的HandleAdapter运行了适配器模式

image-20230601125917649

桥接模式

可以解决类爆炸(扩展性问题)

原理图

image-20230601171709114

image-20230601173443303

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public abstract class Phone {
private Brand brand;

public Phone(Brand brand) {
this.brand = brand;
}

public Phone() {}

public void call() {
brand.call();
}
}

public class FoldePhone extends Phone {
public FoldePhone(Brand brand) {
super(brand);
}

@Override
public void call() {
super.call();
System.out.println("折叠式");
}
}

public abstract class Brand {
public abstract void call();
}

public class XiaoMi extends Brand {
@Override
public void call() {
System.out.println("小米手机Call");
}
}

public class Client {
public static void main(String[] args) {
FoldePhone foldePhone = new FoldePhone(new XiaoMi());
foldePhone.call();
}
}

输出👇
小米手机Call
折叠式

装饰器模式

image-20230601192951753

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class Client {
public static void main(String[] args) {
Coffee coffee = new Coffee();
System.out.println("咖啡");
coffee.cast();
System.out.println("加牛奶");
Milk milk = new Milk(coffee);
milk.cast();
System.out.println("加糖");
Sugar sugar = new Sugar(coffee);
sugar.cast();
}
}

public abstract class Drink {
protected String description;
protected float cast;

public abstract void cast();
}

public abstract class Decorate extends Drink{
protected Drink drink;
}

public class Coffee extends Drink{

public Coffee() {
cast = 7.0f;
description = "咖啡";
}

@Override
public void cast() {
System.out.println("收费: " + cast);
}
}

public class Milk extends Decorate{
public Milk(Drink drink) {
super.drink = drink;
this.cast = 5.0f;
}

@Override
public void cast() {
super.drink.cast = super.drink.cast + this.cast;
System.out.println("花费: " + super.drink.cast);
}
}

输出👇
咖啡
收费: 7.0
加牛奶
花费: 12.0
加糖
花费: 14.0

JDK中的装饰者模式

image-20230601202808625

组合模式

学院 -> 子学院 -> 系 -> 专业 -> 班级

类似树形结构,此方式可灵活添加删除,例如再university和college中间添加一个school

image-20230601214201792

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
@Data
public abstract class OrganizationComponent {
private String name;
private String description;

public OrganizationComponent(String name, String description) {
this.name = name;
this.description = description;
}

public void add(OrganizationComponent component) {
throw new UnsupportedOperationException();
}

public void remove(OrganizationComponent component) {
throw new UnsupportedOperationException();
}

public void print() {
throw new UnsupportedOperationException();
}
}


public class College extends OrganizationComponent{
List<OrganizationComponent> children;

public College(String name, String description) {
super(name, description);
children = new ArrayList<>();
}

@Override
public void add(OrganizationComponent component) {
children.add(component);
}

@Override
public void remove(OrganizationComponent component) {
children.remove(component);
}

@Override
public void print() {
children.forEach(System.out::println);
}
}

public class University extends OrganizationComponent{
List<OrganizationComponent> children;

public University(String name, String description) {
super(name, description);
children = new ArrayList<>();
}

@Override
public void add(OrganizationComponent component) {
children.add(component);
}

@Override
public void remove(OrganizationComponent component) {
children.remove(component);
}

@Override
public void print() {
children.forEach(System.out::println);
}
}

public class Department extends OrganizationComponent {
public Department(String name, String description) {
super(name, description);
}
}

public class Client {
public static void main(String[] args) {
University university = new University("university", "university");
College college1 = new College("college1", "college1");
College college2 = new College("college2", "college2");
Department department1 = new Department("department1" ,"department1");
Department department2 = new Department("department2" ,"department2");
university.add(college1);
university.add(college2);
college1.add(department1);
college1.add(department2);

System.out.println("--university--");
university.print();
System.out.println("--college--");
college1.print();
}
}


输出👇
--university--
OrganizationComponent(name=college1, description=college1)
OrganizationComponent(name=college2, description=college2)
--college--
OrganizationComponent(name=department1, description=department1)
OrganizationComponent(name=department2, description=department2)

外观模式

facade,也叫过程模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口是使得这个一子系统更加容易使用。类似宏

image-20230605115813446

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class Facade {
private DVDPlayer dvdPlayer;
private Fan fan;
private Lamp lamp;

public Facade() {
this.fan = new Fan();
this.lamp = new Lamp();
this.dvdPlayer = new DVDPlayer();
}

public void redy() {
lamp.stop();
}

public void start() {
fan.open();
dvdPlayer.open();
}

public void stop() {
fan.stop();
dvdPlayer.stop();
lamp.open();
}
}

public class DVDPlayer {


public void open() {
System.out.println("DVDPlayer 被开启");
}

public void stop() {
System.out.println("DVDPlayer 被关闭");
}
}

public class Fan {
public void open() {
System.out.println("Fan 被开启");
}

public void stop() {
System.out.println("Fan 被关闭");
}
}

public class Lamp {
public void open() {
System.out.println("Lamp 被开启");
}

public void stop() {
System.out.println("Lamp 被关闭");
}
}

public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.redy();
facade.start();
facade.stop();
}
}

输出👇
Lamp 被关闭
Fan 被开启
DVDPlayer 被开启
Fan 被关闭
DVDPlayer 被关闭
Lamp 被开启

享元模式

也叫蝇量模式,运用共享技术有效的支持大量细粒度的对象。

image-20230605171924732

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class Factory {
private Map<String, FruitAbs> fruitAbs;

public Factory() {
this.fruitAbs = new HashMap<>();
}

public FruitAbs getFruit(String fruitName) {
if (!fruitAbs.containsKey(fruitName)) {
NormalFruit normalFruit = new NormalFruit();
if (fruitName.equals("菠萝")) {
normalFruit.setName("🍍");
} else {
normalFruit.setName("otherfruit");
}
fruitAbs.put(fruitName, normalFruit);
}
return fruitAbs.get(fruitName);
}
}

@Data
public abstract class FruitAbs {
private String name;
public abstract void description();
}

public class NormalFruit extends FruitAbs{
@Override
public void description() {
System.out.println("常见的水果,很可口!");
}
}

public class Client {
public static void main(String[] args) {
Factory factory = new Factory();
FruitAbs boluo = factory.getFruit("菠萝");
FruitAbs xigua = factory.getFruit("西瓜");

System.out.println(boluo);
boluo.description();

System.out.println(xigua);
xigua.description();
}
}

输出👇
FruitAbs(name=🍍)
常见的水果,很可口!
FruitAbs(name=otherfruit)
常见的水果,很可口!

JDK中Integer使用了此模式,见下。其中IntegerCache缓存了部分int值用于直接返回。超过这个值才会new 新的对象。

1
2
3
4
5
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

代理模式

  1. 为一个对象提供一个替身,可通过这个替身对目标对象进行增强,扩展功能。
  2. 主要有三种:静态代理、动态代理(JDK代理、接口代理)、Cglib代理(可以在内存动态的创建对象,而不需要实现接口,属于动态代理)
静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者继承相同的父类,下图

image-20230605194430423

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public interface TargetInterface {
public void test();
}

public class Target implements TargetInterface {
@Override
public void test() {
System.out.println("被代理对象test");
}
}

public class TargetProxy implements TargetInterface{
private TargetInterface targetInterface;

public TargetProxy(TargetInterface targetInterface) {
this.targetInterface = targetInterface;
}

@Override
public void test() {
System.out.println("开始代理");
targetInterface.test();
System.out.println("代理结束");
}
}

public class Client {
public static void main(String[] args) {
Target target = new Target();
TargetProxy targetProxy = new TargetProxy(target);
targetProxy.test();
}
}

输出👇
开始代理
被代理对象test
代理结束
动态代理
  1. 代理对象不需要实现接口,但是目标对象要实现接口,否则不能用动态代理
  2. 代理对象的生成,是利用JDK的API,动态的在内存中构建对象
  3. 动态代理也叫:JDK代理、接口代理

image-20230605194445273

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public interface TargetInterface {
public void test();
}

public class TargetProxy {
private Object target;

public TargetProxy(Object target) {
this.target = target;
}

public Object getIntennce() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("JDK动态代理开始");
Object invoke = method.invoke(target, args);
System.out.println("JDK动态代理结束");
return invoke;
});
}
}

public class Target implements TargetInterface {
@Override
public void test() {
System.out.println("被代理对象test");
}
}

public class Client {
public static void main(String[] args) {
Target target = new Target();
TargetProxy targetProxy = new TargetProxy(target);
TargetInterface intennce = (TargetInterface) targetProxy.getIntennce();
intennce.test();
}
}

输出👇
JDK动态代理开始
被代理对象test
JDK动态代理结束
Cglib代理
  1. Cglib代理也叫做子类代理,它是内从中构建子类对象从而实现对目标对象功能增强的扩展
  2. 静态代理和JDK代理模式都要求目标对象是实现一个接口的,但是有时候对象只是一个单独的对象,并没有实现任何接口,这个时候可使用目标对象子类来实现代理
  3. Cglib代理有被应用到Spring AOP中实现方法拦截
  4. 在AOP中如何选择代理模式
    1. 目标对象需要实现接口,用JDK代理
    2. 目标对象不需要实现接口,用Cglib代理🎈🎈🎈
  5. Cglib底层是通过使用字节码处理框架ASM来转换字节码并生成新的类

image-20230605205138326

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class TargetProxy implements MethodInterceptor {

private Object target;

public TargetProxy(Object target) {
this.target = target;
}

public Object getInstance() {
// 创建子类工具
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(target.getClass());
// 设置回调函数
enhancer.setCallback(this);
// 返回代理对象
return enhancer.create();
}

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib代理开始");
Object resultValue = method.invoke(target, objects);
//Object resultValue = methodProxy.invokeSuper(o, objects);
System.out.println("cglib代理结束");
return resultValue;
}

}

public class Target {

public void test() {
System.out.println("test");
}

@Override
public String toString() {
return "Target{}";
}
}

public class Client {
public static void main(String[] args) {
Target target = new Target();
TargetProxy targetProxy = new TargetProxy(target);
Target instance = (Target) targetProxy.getInstance();
instance.test();
}
}

cglib代理开始
test
cglib代理结束

模板模式

  1. 在一个抽象公开定义了执行它的方法的模板,它的子类可以按需重写方法的实现,但调用将以抽象类中定义的方法执行
  2. 故模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法结构,就可以重定义算法的某些特定步骤。

image-20230606094203455

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public interface FruitJuiceAbs {
default void make() {
prepare();
cut();
squeeze();
}
void prepare();
void cut();
void squeeze();
}

public class FruitJuice implements FruitJuiceAbs{
@Override
public void prepare() {
System.out.println("准备🍍");
}

@Override
public void cut() {
System.out.println("切割🍍");
}

@Override
public void squeeze() {
System.out.println("榨🍍汁");
}
}

public class Client {
public static void main(String[] args) {
FruitJuice fruitJuice = new FruitJuice();
fruitJuice.make();
}
}

准备🍍
切割🍍
榨🍍汁

spring中ConfigurableApplicationContext使用了模板模式

ConfigurableApplicationContext

image-20230606171324065

ConfigurableApplicationContext的实现子类AbstractApplicationContext对refresh进行了实现

image-20230606171341275

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 此处本类obtainFreshBeanFactory中getBeanFactory并没有实现,交给了子类
this.prepareBeanFactory(beanFactory);

try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}

this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}

}
}

AbstractApplicationContex的子类AbstractRefreshableApplicationContext中getBeanFactory的实现

1
2
3
4
5
6
7
8
9
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized(this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext");
} else {
return this.beanFactory;
}
}
}

命令模式

  1. 在软件设计中,我们要想某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是那个。我们只需在程序运行时指定具体的请求接收者,此时可以使用命令模式来设计

image-20230606181358678

图解

  1. Invoker是调用者角色
  2. Command是命令角色,需要执行所有命令都在这里,可以是接口或抽象类
  3. Receiver接受者角色,知道如何实施和执行一个请求相关的操作
  4. ConcreteCommand 将一个接收者对象与一个动作绑定,调用接收者相应的操作,实现execute

image-20230606200029342

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
public interface TVCommand {
void execute();
void undo();
}

public class TVController {
private List<TVCommand> onList;
private List<TVCommand> offList;
private TVCommand withdraw;

public TVController() {
onList = new ArrayList<>();
offList = new ArrayList<>();
}

public void addCommand(int i, TVCommand onCommand, TVCommand offCommand) {
onList.add(i, onCommand);
offList.add(i, offCommand);
}

public void on(int i) {
// 执行
onList.get(i).execute();
// 记录
withdraw = onList.get(i);
}

public void off(int i) {
offList.get(i).execute();
withdraw = offList.get(i);
}

public void withdraw() {
withdraw.undo();
}
}

public class TVNoCommand implements TVCommand {

@Override
public void execute() {
}

@Override
public void undo() {

}
}

public class TVOffCommand implements TVCommand{
private TVReceiver receiver;

public TVOffCommand(TVReceiver receiver) {
this.receiver = receiver;
}

@Override
public void execute() {
receiver.off();
}

@Override
public void undo() {
receiver.on();
}
}

public class TVOnCommand implements TVCommand{
private TVReceiver receiver;

public TVOnCommand(TVReceiver receiver) {
this.receiver = receiver;
}

@Override
public void execute() {
receiver.on();
}

@Override
public void undo() {
receiver.off();
}
}

public class TVReceiver {
public void on() {
System.out.println("TV on");
}

public void off() {
System.out.println("TV off");
}
}

public class Client {
public static void main(String[] args) {
TVReceiver tvReceiver = new TVReceiver();
TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver);
TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver);
TVController tvController = new TVController();
tvController.addCommand(0, tvOnCommand, tvOffCommand);

System.out.println("---------开启---------");
tvController.on(0);
System.out.println("---------关闭---------");
tvController.off(0);
System.out.println("---------撤销---------");
tvController.withdraw();
}
}

---------开启---------
TV on
---------关闭---------
TV off
---------撤销---------
TV on

JDBCTemplate中的命令模式

image-20230606214629332

访问者模式

  1. 解决数据结构和操作隔离的问题
  2. 基本原理:在被访问的类里面加一个对外提供接待访问者的接口

image-20230610185814832

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public interface ComputerVisit {
void visit(KeyBoard keyBoard);
void visit(Mouse mouse);
void visit(Monitor monitor);
}

public class ComputerVisitor implements ComputerVisit {
@Override
public void visit(KeyBoard keyBoard) {
System.out.println("访问键盘");
}

@Override
public void visit(Mouse mouse) {
System.out.println("访问鼠标");
}

@Override
public void visit(Monitor monitor) {
System.out.println("访问显示器");
}
}

public interface ComputerAbs {
void accept(ComputerVisitor computerVisitor);
}

public class KeyBoard implements ComputerAbs{
@Override
public void accept(ComputerVisitor computerVisitor) {
computerVisitor.visit(this);
}
}

public class Monitor implements ComputerAbs{
@Override
public void accept(ComputerVisitor computerVisitor) {
computerVisitor.visit(this);
}
}

public class Mouse implements ComputerAbs{
@Override
public void accept(ComputerVisitor computerVisitor) {
computerVisitor.visit(this);
}
}

public class Computer implements ComputerAbs {

private ComputerAbs[] computer;

public Computer() {
computer = new ComputerAbs[]{new Mouse(), new KeyBoard(), new Monitor()};
}

@Override
public void accept(ComputerVisitor computerVisitor) {
for (int i = 0; i < computer.length; i++) {
computer[i].accept(computerVisitor);
}
}
}

public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
ComputerVisitor computerVisitor = new ComputerVisitor();
computer.accept(computerVisitor);
}
}

迭代器模式

当遍历集合元素会用到不同的方式实现,可以考虑迭代器

数据和遍历方式分开

image-20230610202243007

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public interface CreateIterator {
Iterator getIterator();
String getName();
}

public class CreateCollegeIterator implements CreateIterator{
private List<College> collegeList;
public CreateCollegeIterator(List<College> collegeList) {
this.collegeList = collegeList;
}

@Override
public Iterator getIterator() {
return new CollegeIterator(collegeList);
}

@Override
public String getName() {
return "学院信息";
}
}

public class CollegeIterator implements Iterator {
private List<College> collegeList;
private int index;

public CollegeIterator(List<College> collegeList) {
this.collegeList = collegeList;
}

@Override
public boolean hasNext() { return index != collegeList.size(); }

@Override
public Object next() {
if (index >= collegeList.size()) {
throw new NoSuchElementException("元素不存在");
}
College college = collegeList.get(index);
index ++;
return college;
}

@Override
public void remove() {
}
}

@Data
@AllArgsConstructor
public class College {
private String name;
private String description;
}

public class Client {

public static void main(String[] args) {
List<College> list = Arrays.asList(new College("计算机学院", "计算机学院"),
new College("人工智能学院", "人工智能学院"),
new College("计算机与软件工程学院", "计算机与软件工程学院"));
CreateCollegeIterator createCollegeIterator = new CreateCollegeIterator(list);
Iterator iterator = createCollegeIterator.getIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}

College(name=计算机学院, description=计算机学院)
College(name=人工智能学院, description=人工智能学院)
College(name=计算机与软件工程学院, description=计算机与软件工程学院)

JDK中ArrayList使用了迭代器

观察者模式

观察者模式:对象之间多对一以来的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化。

image-20230612173019916

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public abstract class Observer {
protected Subject subject;
public abstract void update();
}

public class Subject {
public Subject() {
observerList = new ArrayList<>();
}
List<Observer> observerList;
private int state;

public void setState(int state) {
this.state = state;
notifyAllObserver();
}

public int getState() {
return state;
}

public void attach(Observer observer) {
observerList.add(observer);
}

public void notifyAllObserver() {
observerList.forEach(Observer::update);
}
}

public class BinaryObserver extends Observer {

public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("二进制: " + Integer.toBinaryString(subject.getState()));
}
}

public class HexaObserver extends Observer{

public HexaObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("十六进制: " + Integer.toHexString(subject.getState()));
}
}

public class OctalObserver extends Observer{

public OctalObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println("八进制: " + Integer.toOctalString(subject.getState()));
}
}

public class Client {
public static void main(String[] args) {
Subject subject = new Subject();
new BinaryObserver(subject);
new HexaObserver(subject);
new OctalObserver(subject);
int num = 100;
System.out.println("输入数字(十进制): " + num);
subject.setState(num);
}
}

输入数字: 100
二进制: 1100100
十六进制: 64
十进制: 144

JDK中的Observable使用此模式

中介者模式

  1. 对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理
  2. MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

image-20230612175310685

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@AllArgsConstructor
public class User {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void sendMessage(String message) {
ChatRoom.showMessage(this, message);
}
}

public class ChatRoom {
public static void showMessage(User user, String message) {
String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm-ss"));
System.out.println(time + " " + user.getName() + ": " + message);
}
}

public class Client {
public static void main(String[] args) throws InterruptedException {
User jack = new User("Jack");
User dick = new User("Dick");
jack.sendMessage("hello");
Thread.sleep(2000);
dick.sendMessage("hi");
}
}

2023-06-12 18:03-37 Jack: hello
2023-06-12 18:03-39 Dick: hi

备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

image-20230612191948546

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class Originator {
private String state;

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public Memento getCurrentMemento() {
return new Memento(state);
}
}

@Data
public class Memento {

private String state;

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public Memento(String state) {
this.state = state;
}
}

public class Notes {
private List<Memento> mementoList;

public Notes() {
mementoList = new ArrayList<>();
}

public void add(Memento memento) {
mementoList.add(memento);
}

public Memento get(int index) {
return mementoList.get(index);
}
}

public class Client {
public static void main(String[] args) {
Notes notes = new Notes();
Originator originator = new Originator();
originator.setState("#1");
notes.add(originator.getCurrentMemento());
originator.setState("#2");
originator.setState("#3");
notes.add(originator.getCurrentMemento());
originator.setState("#4");

System.out.println(notes.get(0));
System.out.println(notes.get(1));
}
}

Memento(state=#1)
Memento(state=#3)

解释器模式

状态模式

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

image-20230612193123701

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public interface State {
void doAction(Content content);
}

public class Content {
private State state;

public State getState() {
return state;
}

public void setState(State state) {
this.state = state;
}
}

public class StartState implements State{
@Override
public void doAction(Content content) {
content.setState(this);
}

@Override
public String toString() {
return "start state";
}
}

public class StopState implements State{
@Override
public void doAction(Content content) {
content.setState(this);
}

@Override
public String toString() {
return "stop state";
}
}

public class Client {
public static void main(String[] args) {
Content content = new Content();
// start
StartState startState = new StartState();
startState.doAction(content);
System.out.println(content.getState());
// stop
StopState stopState = new StopState();
stopState.doAction(content);
System.out.println(content.getState());
}
}

start state
stop state

策略模式

主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

image-20230612195335197

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public interface Strategy {
int operation(int num1, int num2);
}

public class StrategyAdd implements Strategy{
@Override
public int operation(int num1, int num2) {
return num1 + num2;
}
}

public class StrategyExcept implements Strategy{
@Override
public int operation(int num1, int num2) {
return num1 / num2;
}
}

public class StrategyMinus implements Strategy{
@Override
public int operation(int num1, int num2) {
return num1 - num2;
}
}

public class Content {
private Strategy strategy;

public int doOperation(int num1, int num2) {
return strategy.operation(num1, num2);
}

public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
}

public class Client {
public static void main(String[] args) {
Content content = new Content();
StrategyAdd strategyAdd = new StrategyAdd();
int num1 = 100, num2 = 200;
content.setStrategy(strategyAdd);
System.out.print(num1 + " + " + num2 + " = ");
System.out.println(content.doOperation(num1, num2));
}
}

100 + 200 = 300

职责链模式