设计模式期末复习(java)

简单工厂

uml类图

工厂模式

优点:

1.使用工厂方法可以让用户的代码和某个特定类的子类的代
码解耦。
2.工厂方法使用户不必知道它所使用的对象是怎样被创建的
,只需知道该对象有哪些方法即可。

缺点

1.不符合开闭原则
2.职责过重
3.不易扩展 adfdqwwa

代码

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
//创建接口
public interface Shape {
void draw();
}
public class Rectangle implements Shape {

@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
//接口实体类
public class Square implements Shape {

@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle implements Shape {

@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
//创建一个工厂,生成基于给定信息的实体类的对象
public class ShapeFactory {

//使用 getShape 方法获取形状类型的对象
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
//使用该工厂,通过传递类型信息来获取实体类的对象。
public class FactoryPatternDemo {

public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();

//获取 Circle 的对象,并调用它的 draw 方法
Shape shape1 = shapeFactory.getShape("CIRCLE");

//调用 Circle 的 draw 方法
shape1.draw();

//获取 Rectangle 的对象,并调用它的 draw 方法
Shape shape2 = shapeFactory.getShape("RECTANGLE");

//调用 Rectangle 的 draw 方法
shape2.draw();

//获取 Square 的对象,并调用它的 draw 方法
Shape shape3 = shapeFactory.getShape("SQUARE");

//调用 Square 的 draw 方法
shape3.draw();
}
}

抽象工厂

uml类图

抽象工厂

优点:

1.抽象工厂模式可以为用户创建一系列相关的对象,使得用
户和创建这些对象的类脱耦。

2.使用抽象工厂模式可以方便的为用户配置一系列对象。用
户使用不同的具体工厂就能得到一组相关的对象,同时也
能避免用户混用不同系列中的对象。

3.在抽象工厂模式中,面对新的“具体产品” ,可以随时
增加“具体工厂”为用户提供一组相关的对象。

缺点

1.不符合开闭原则:当需要新增一种产品时,除了需要添加新的具体产品类,还需要修改抽象工厂的接口和所有具体工厂的实现类,违背了开闭原则。

2.增加了系统的复杂性:引入抽象工厂模式会增加类的数量,增加了系统的复杂性和理解难度。

3.不易扩展新的产品族:抽象工厂模式适用于一系列相互依赖的产品对象的创建,但当需要增加新的产品族时,需要修改抽象工厂接口及其所有具体工厂的实现类,不易扩展新的产品族。

代码

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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//为形状创建一个接口。
public interface Shape {
void draw();
}

//创建实现接口的实体类。
public class Rectangle implements Shape {

@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
//Square.java
public class Square implements Shape {

@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
//Circle.java
public class Circle implements Shape {

@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
//为颜色创建一个接口。
public interface Color {
void fill();
}

//创建实现接口的实体类。
public class Red implements Color {

@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
//Green.java
public class Green implements Color {

@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
//Blue.java
public class Blue implements Color {

@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
//为 Color 和 Shape 对象创建抽象类来获取工厂。

//AbstractFactory.java
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape);
}
//创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。

//ShapeFactory.java
public class ShapeFactory extends AbstractFactory {

@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}

@Override
public Color getColor(String color) {
return null;
}
}
//ColorFactory.java
public class ColorFactory extends AbstractFactory {

@Override
public Shape getShape(String shapeType){
return null;
}

@Override
public Color getColor(String color) {
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
//创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。
FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
//使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。
AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {

//获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

//获取形状为 Circle 的对象
Shape shape1 = shapeFactory.getShape("CIRCLE");

//调用 Circle 的 draw 方法
shape1.draw();

//获取形状为 Rectangle 的对象
Shape shape2 = shapeFactory.getShape("RECTANGLE");

//调用 Rectangle 的 draw 方法
shape2.draw();

//获取形状为 Square 的对象
Shape shape3 = shapeFactory.getShape("SQUARE");

//调用 Square 的 draw 方法
shape3.draw();

//获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

//获取颜色为 Red 的对象
Color color1 = colorFactory.getColor("RED");

//调用 Red 的 fill 方法
color1.fill();

//获取颜色为 Green 的对象
Color color2 = colorFactory.getColor("GREEN");

//调用 Green 的 fill 方法
color2.fill();

//获取颜色为 Blue 的对象
Color color3 = colorFactory.getColor("BLUE");

//调用 Blue 的 fill 方法
color3.fill();
}
}

单例模式(优缺点)

uml类图

单例

优点:

系统内存中该类只存在一个对象,节省了系统资源,对于一些需要
频繁创建销毁的对象,使用单例模式可以提高系统性能。

缺点

当想实例化一个单例类的时候,必须要记住使用相应的获取对象的
方法,而不是使用 new ,可能会给其他开发人员造成困扰,特别是
看不到源码的时候。

代码

饿汉

1
2
3
4
5
6
7
8
9
10
public class EHan {
private static EHan eh = new EHan();

private EHan() {
}

public static EHan init() {
return eh;
}
}

懒汉
1
2
3
4
5
6
7
8
9
10
11
public class LanHan {
private static LanHan lh;
private LanHan() {}

public static LanHan init() {
if (lh == null) {
lh = new LanHan();
}
return lh;
}
}

双重锁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class LanHan {
private static volatile LanHan lh;
private LanHan() {}

public static LanHan init() {
if (lh == null) {
synchronized (LanHan.class) {
if (lh == null) {
lh = new LanHan();
}
}
}
return lh;
}
},

静态内部类
1
2
3
4
5
6
7
8
9
10
public class Wai {
private Wai() {}
private static class Nei {
private static final Wai wai = new Wai();
}
public static Wai init() {
return Nei.wai;
}
}

适配器模式

uml类图

适配器

优点:

1.目标( Target )和被适配者( Adaptee )是完
全解耦的关系。

2.适配器模式满足“开 - 闭原则”。当添加一个
实现 Adaptee 接口的新类时,不必修改
Adapter , Adapter 就能对这个新类的实例进行
适配。

缺点

1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

装饰器模式

uml类图

装饰

优点:

1.被装饰者和装饰者是松耦合关系。由于装饰( Decorator )仅仅依
赖于抽象组件( Component ),因此具体装饰只知道它要装饰的对象是
抽象组件的某一个子类的实例,但不需要知道是哪一个具体子类。

2.装饰模式满足“开 - 闭原则”。不必修改具体组件,就可以增加新
的针对该具体组件的具体装饰。

3.可以使用多个具体装饰来装饰具体组件的实例。

4.装饰者模式是继承的有力补充,且比继承灵活,可以在不改变原有对象
的情况下动态地给一个对象扩展功能,即插即用

缺点

1.增加了系统复杂性:引入适配器类增加了系统的复杂性,因为需要额外的类来实现适配器功能。

2.可能存在性能损失:适配器模式在转换接口的过程中可能需要进行额外的处理和转换,这可能导致一定的性能损失。

3.不适用于过多的适配器:如果系统中存在大量的适配器类,可能会导致代码混乱和难以维护。

代码

家案例

接口

1
2
3
4
5
public interface Component {
StringBuffer show(StringBuffer str);

}


1
2
3
4
5
6
7
8
9
10
11
public class MyNewHouse implements Component{
private String name;
public MyNewHouse(String name) {
this.name=name;
}
@Override
public StringBuffer show(StringBuffer str) {
return str.append( "this is"+name+"home where has:");
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Furniture implements Component{
private Component com;
public Furniture(Component com) {
this.com=com;
}
@Override
public StringBuffer show(StringBuffer str) {
if(com!=null) {
return com.show(str);
}else {
return null;
}
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BingXiang extends ZhuangShi{

public BingXiang(Component com) {
super(com);

}
@Override
public StringBuffer show(StringBuffer str) {
super.show(str);
return str.append("bingxiang");
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ShaFa extends Furniture{
public ShaFa(Component com) {
super(com);
}
@Override
public StringBuffer show(StringBuffer str) {
super.show(str);
return str.append(" shafa");
}


}

1
2
3
4
5
6
7
8
9
10
11
12
public class TV extends Furniture{
public TV(Component com) {
super(com);
}
@Override
public StringBuffer show(StringBuffer str) {
super.show(str);
return str.append("tv");
}

}

1
2
3
4
5
6
7
8
9
10
public class Test {
public static void main(String[] args) {
MyNewHouse mnh=new MyNewHouse("zhangsan");
TV tv=new TV(mnh);
ShaFa sf=new ShaFa(tv);
BingXiang bx=new BingXiang(sf);
System.out.println(bx.show(new StringBuffer()));
}

}

鸟案例

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 abstract class Bird {
public abstract int fly();

}
public class HuoJian extends JiNeng{
public final int distance=1000;
public HuoJian(Bird bird) {
super(bird);
}
@Override
public int fly() {
return bird.fly()+distance;
}
public int juli() {
System.out.println(""+distance+"��");
return distance;
}

}
public abstract class JiNeng extends Bird {
public Bird bird;
public JiNeng(Bird bird) {
this.bird=bird;
}
}
public class LuoXuanJiang extends JiNeng{
public final int distance=50;
public LuoXuanJiang(Bird bird) {
super(bird);
}
@Override
public int fly() {
return bird.fly()+distance;
}
public int juli() {
System.out.println("����������������ǰ����"+distance+"��");
return distance;
}
}
public class MaQue extends Bird{
public final int distance=100;

@Override
public int fly() {
return distance;
}

}
public class Test {
public static void main(String[] args) {
Bird bird=new MaQue();
System.out.println("��ֻ����Է��У�"+bird.fly());
System.out.println("-------------------");
LuoXuanJiang b1=new LuoXuanJiang(bird);
b1.juli();
System.out.println("��ֻ����Է��У�"+b1.fly());
System.out.println("-------------------");
LuoXuanJiang b2=new LuoXuanJiang(b1);
b2.juli();
System.out.println("��ֻ����Է��У�"+b2.fly());
System.out.println("-------------------");
HuoJian b3=new HuoJian(b2);
b3.juli();
System.out.println("��ֻ����Է��У�"+b3.fly());
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
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 abstract class AbstractComputer {
public abstract String getMsg();
public abstract int getPrice();

}

public class BaseComputer extends AbstractComputer{
@Override
public String getMsg() {
return "电脑";
}
@Override
public int getPrice() {
return 5000;
}

}
public class NeiCun extends ZhuangShi{
public NeiCun(AbstractComputer com) {
super(com);
}
@Override
public String getMsg() {
return super.getMsg()+"+1个内存";
}
@Override
public int getPrice() {
return super.getPrice()+500;
}

}
public class YingPan extends ZhuangShi{
public YingPan(AbstractComputer com) {
super(com);
}
@Override
public String getMsg() {
return super.getMsg()+"+1个硬盘";
}
@Override
public int getPrice() {
return super.getPrice()+1000;
}

}
public class ZhuangShi extends AbstractComputer{
private AbstractComputer com;
public ZhuangShi(AbstractComputer com) {
this.com=com;
}
@Override
public String getMsg() {
return com.getMsg();
}
@Override
public int getPrice() {
return com.getPrice();
}

}
public class Test {
public static void main(String[] args) {
AbstractComputer com=new BaseComputer();
com=new NeiCun(com);
com=new YingPan(com);
com=new NeiCun(com);
System.out.println(com.getMsg()+"价格"+com.getPrice());

}

}

代理模式

uml类图

代理

优点:

1.代理模式可以屏蔽用户真正请求的对象,使用户程序和
真正的对象之间解耦。
2.使用代理来担当那些创建耗时的对象的替身。

缺点

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 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
//创建接口
public interface RenWu
{
public void waTu();
public void caoCai();
}
//user 继承Renwu
public class User implements RenWu{
@Override
public void waTu() {
System.out.println("工人使用挖掘机挖土");
}
@Override
public void caoCai() {
System.out.println("工人使用挖掘机炒菜");
}

}
//静态代理类
public class DaiLiStatic implements RenWu{
private RenWu work;
public DaiLiStatic(RenWu work) {
this.work=work;
}
@Override
public void waTu() {
System.out.println("劳务中心抽取费用");
work.waTu();
}
@Override
public void caoCai() {
System.out.println("劳务中心抽取费用");
work.caoCai();

}
}
//测试类
public class Test {
public static void main(String[] args) {
User user=new User();//已存在的工人
DaiLiStatic dl=new DaiLiStatic(user);//劳务中心找到工人
//让劳务中心做事
dl.waTu();
dl.caoCai();
}

}

登录案例

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
public interface UserDao {
public void doLogin();
public void doRegister();


}
public class UserDaoImpl implements UserDao{
@Override
public void doLogin() {
System.out.println("ִ执行登录");
}
@Override
public void doRegister() {
System.out.println("ִ执行注册");

}

}
public class StaticUser implements UserDao{//实现抽象主题
private UserDao dao;//实例具体主题
public StaticUser(UserDao dao) {//传入实际主题
this.dao=dao;
}
@Override
public void doLogin() {
System.out.println("代理机构抽取佣金");
dao.doLogin();
}

@Override
public void doRegister() {
System.out.println("代理机构抽取佣金");
dao.doRegister();
}

}
public class Test {
public static void main(String[] args) {
UserDao dao=new UserDaoImpl();
StaticUser dl=new StaticUser(dao);
dl.doLogin();
dl.doRegister();
}

}

动态代理

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
// 定义接口
interface Calculator {
int add(int a, int b);
}

// 实现接口的类
class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
}

// 实现InvocationHandler接口的代理类
class CalculatorProxy implements InvocationHandler {
private final Object target;

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

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method invocation");
Object result = method.invoke(target, args);
System.out.println("After method invocation");
return result;
}
}

public class DynamicProxyExample {
public static void main(String[] args) {
// 创建目标对象
Calculator calculator = new CalculatorImpl();

// 创建代理对象
Calculator proxy = (Calculator) Proxy.newProxyInstance(
Calculator.class.getClassLoader(),
new Class[]{Calculator.class},
new CalculatorProxy(calculator)
);

// 调用代理对象的方法
int result = proxy.add(2, 3);
System.out.println("Result: " + result);
}
}

责任链模式

uml类图

责任链

优点:

1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。

缺点

1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。

代码

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 interface MyFilter {
public String doFilter(String name);
}
//具体处理者
public class FaceFilter implements MyFilter{
@Override
public String doFilter(String name) {
String tmp=name.replace("(:)", "!!");
System.out.println("经过表情包过滤");
return tmp;
}

}
public class MsgFilter implements MyFilter{
@Override
public String doFilter(String name) {
String tmp=name.replace("敏感", "**");
System.out.println("经过表情包过滤");
return tmp;
}

}
public class MyFilterChain implements MyFilter{
//过滤器每一个人节点都是位移不重复set
private Set<MyFilter> filters=new HashSet<MyFilter>();
public MyFilterChain addFilter(MyFilter filter) {
this.filters.add(filter);

return this;
}
@Override
public String doFilter(String name) {
String tmp=name;
for(MyFilter filter:filters) {
tmp=filter.doFilter(tmp);
}
return tmp;
}

}
public class Test {
public static void main(String[] args) {
String str="大家敏感好(:)天气不错,铭感风有点大(:)(:),哈哈";

MyFilterChain chain = new MyFilterChain();
chain.addFilter(new FaceFilter()).addFilter(new MsgFilter());

String result=chain.doFilter(str);
System.out.println(result);
}

}

观察者模式

uml类图

观察者

优点:

1.具体主题和具体观察者是松耦合关系。由于主题( Subject )接口仅仅依
赖于观察者( Observer )接口,因此具体主题只是知道它的观察者是实现
观察者( Observer )接口的某个类的实例,但不需要知道具体是哪个类。
同样,由于观察者仅仅关联于主题( Subject )接口,因此具体观察者只是
知道它依赖的主题是实现主题( subject )接口的某个类的实例,但不需要
知道具体是哪个类。(即两者都只需和接口打交道,相互扩展性就会高了很
多)

2.观察模式满足“开 - 闭原则”。主题( Subject )接口仅仅依赖于观察者
( Observer )接口,这样,我们就可以让创建具体主题的类也仅仅是依赖
于观察者( Observer )接口,因此如果增加新的实现观察者( Observer )
接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类
仅仅依赖于主题( Observer )接口,如果增加新的实现主题( Subject )
接口的类,也不必修改创建具体观察者类的代码。

缺点

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

策略模式

uml类图

策略

优点:

1.上下文( Context )和具体策略( ConcreteStrategy )是松耦合关系。
2.策略模式满足“开 - 闭原则”。当增加新的具体策略时,不需要修改上下文类的代码,上下文就可以引用新的具体策略的实例

缺点

1、策略类会增多。 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
66
67
68
69
70
71
72
73
import java.util.ArrayList;
import java.util.List;

// 主题接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers(String message);
}

// 具体主题类
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();

@Override
public void attach(Observer observer) {
observers.add(observer);
}

@Override
public void detach(Observer observer) {
observers.remove(observer);
}

@Override
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}

// 观察者接口
interface Observer {
void update(String message);
}

// 具体观察者类
class ConcreteObserver implements Observer {
private String name;

public ConcreteObserver(String name) {
this.name = name;
}

@Override
public void update(String message) {
System.out.println(name + " 收到消息: " + message);
}
}

// 示例用法
public class ObserverExample {
public static void main(String[] args) {
// 创建主题和观察者
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("观察者1");
Observer observer2 = new ConcreteObserver("观察者2");

// 将观察者附加到主题上
subject.attach(observer1);
subject.attach(observer2);

// 通知观察者
subject.notifyObservers("你好,世界!");

// 从主题上分离观察者1
subject.detach(observer1);

// 再次通知观察者
subject.notifyObservers("观察者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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public interface JiSuan {
public double jiSuanPrice(double price,int n);

}

public class PuTong implements JiSuan{
@Override
public double jiSuanPrice(double price, int n) {
return price*n;
}

}

public class ZhongJi implements JiSuan{
@Override
public double jiSuanPrice(double price, int n) {
return price*n*0.9;
}

}

public class GaoJi implements JiSuan{
@Override
public double jiSuanPrice(double price, int n) {
return price*n*0.8;
}

}

public class MyContext {
private JiSuan jisuan;
public MyContext(JiSuan jisuan) {
this.jisuan=jisuan;
}
public double showPice(double price,int n) {
return jisuan.jiSuanPrice(price, n);
}

}
public class Test {
public static void main(String[] args) {
MyContext c1=new MyContext(new PuTong());
MyContext c2=new MyContext(new GaoJi());
MyContext c3=new MyContext(new ZhongJi());

System.out.println("pt"+c1.showPice(300, 1));
System.out.println("zj"+c3.showPice(300, 1));
System.out.println("gj"+c2.showPice(300, 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
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
public interface CeLuo {
public String getQu();
public String getDo();

}

public class ZouLu implements CeLuo{
@Override
public String getQu() {
return "走路";
}
@Override
public String getDo() {
return "还书";
}

}

public class QiChe implements CeLuo{
@Override
public String getQu() {
return "骑车";
}
@Override
public String getDo() {
return "看书";
}

}

public class KaiChe implements CeLuo{
@Override
public String getQu() {
return "开车";
}
@Override
public String getDo() {
return "paoniu";
}

}

public class MyContext {
private CeLuo cl;
public MyContext(CeLuo cl) {
this.cl=cl;
}
public String toDo() {
return cl.getQu()+"ȥ"+cl.getDo();
}

}

public class Test {
public static void main(String[] args) {
MyContext m1=new MyContext(new ZouLu());
System.out.println(m1.toDo());

MyContext m2=new MyContext(new QiChe());
System.out.println(m2.toDo());

MyContext m3=new MyContext(new KaiChe());
System.out.println(m3.toDo());
}

}

设计模式分类

创建型模式,共四种:
单例模式、简单工厂模式、工厂方法模式、抽象工
厂模式。
结构型模式,共三种:
适配器模式、装饰者模式、代理模式。
行为型模式,共三种:
策略模式、观察者模式、责任链模式。