设计模式总结

1.参考网址

学习参考的网址:

http://c.biancheng.net/view/1351.html


2.设计模式分类(三大类二十三种)

  • 创建型模式用于描述怎么创建对象
  • 结构型模式用于描述如何将类/对象按某种布局组成更大的结构
  • 行为型模式用于描述类/对象之间如何相互协作共同完成单个对象都无法单独完成的任务,如何分配职责

image-20231009170032870


3.统一建模语言(UML)

1. 类图(9类):用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、部署图
2. 类
3. 接口
4. 类之间关系

3.1 类(类名、属性和操作之间有分割线的矩形)

具有相同属性、方法、关系的对象抽象,封装了数据和行为。

1. 类名(字符串)
    举例: Student

2. 属性([可见性]属性名:类型[=默认值])
    举例: -name:String
    可见性取值:
        + 公有 public
        - 私有 private
        # 受保护 protected
        ~ 朋友 friendly

3.操作([可见性]函数名称(函数参数列表)[:返回类型])
    举例: +display():void
  • 学生类的UML图举例

3.2 接口(带名称的小圆圈)

3.3 类图(静态模型)

1. 类图中的类可以通过某种编程 语言直接实现。
2. 类图在软件系统开发的整个生命周期都是有效的。
3. 它是面向对象系统的建模中最常见的图。
  • 举例:(计算长方形和圆形的周长与面积)

3.4 类之间的关系(六个)

1. 依赖关系  - - - -> (带虚线的箭头)

2. 关联关系   
    2.1 双向关联:  <一一> / 一一
    2.2 单向关联:  一一>
    2.3 关联分为一般关联 聚合 组合

3. 聚合关系(强关联)   部分一一◇整体
    整体和部分之间的关系 -- has a的关系
    部分离开整体也可以存在

4. 组合关系(更强烈的聚合关系) 部分部分一一◆整体
    整体和部分之间的关系 -- cxmtains-a的关系
    组合关系中增加整体对象可以控制部分对象的生命周期(整体死了部分也就死了)

5. 泛化关系(耦合度最大)  一一▷
    表示一般与特殊的关系 -- is a的关系(继承)

6. 实现关系  - - - ▷
    表示接口与实现类的关系

3.5 参考文章

http://c.biancheng.net/view/1319.html


4.UML设计七大原则

1. 开闭原则 : 是总纲,它告诉我们要对扩展开放,对修改关闭。 {多态参考的就是这个原则]
2. 里氏替换原则 : 告诉我们不要破坏继承体系
3. 依赖倒置原则 : 告诉我们要面向接口编程
4. 单一职责原则 : 告诉我们实现类要职责单一
5. 接口隔离原则 : 告诉我们在设计接口的时候要精简单一
6. 迪米特法则 : 告诉我们要降低耦合度
7. 合成复用原则 : 告诉我们要优先使用组合或者聚合关系复用,少用继承关系复用。

5.创建型模式(怎样创建对象)

将对象的创建和使用分离,降低系统耦合度,我们不需要关注创建细节,对象的创建由相关的工厂来完成

5.1 创建型模式分类(五个)

1. 单例模式(Singleton)            --对象创建型模式
    1.1 某个类只能生成一个实例,该类提供一个全局访问点供外部获取 (相当于城里面有一个店铺 你要访问店铺必须要通过城门检查)
    1.2 扩展是有限多例模式

2. 原型模式(Prototype)            --对象创建型模式
    2.1 将一个对象作为原型,然后通过复制而克隆出多个新实例

3. 工厂方法(FactoryMethod)          --类创建型模式
    3.1 定义一个创建产品的接口 由子类决定生产什么产品(相当于我定义一个模型样子,具体怎么搞看你子类生产啥)

4. 抽象方法(AbstractFactory)        --对象创建型模式
    4.1 提供一个创建产品族的接口 其每个子类可以生产一系列相关的产品(相关的接口们都给你了 怎么继承覆盖方法是子类决定的)

5. 建造者方式(Builder)              --对象创建型模式
    5.1 将复杂对象分解为多个相对简单的部分 然后根据需求分别创建它们然后构成复杂对象(乐高一样组装)

6.单例模式

6.1 定义和特点

1. 定义:
    采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
2. 特点:
    2.1 单例类只能有一个实例对象
    2.2 该单例对象必须由单例类自行创建[类的构造器访问权限为private,这样就不能用new创建]
    2.3 单例类对外提供一个访问该单例的全局访问点
3. 实现思路
    如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,[就不能用new操作符在类的外部产生类的对象],但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法用于返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

6.2 懒汉式(每次访问都要同步 线程不安全 延迟加载)

类加载时不生成单例,第一次调用getInstance方法才会创建单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LazySingleton
{
private static volatile LazySingleton instance=null; //保证 instance 在所有线程中同步
private LazySingleton(){
//private 避免类在外部被实例化
}

//编写多线程不删除关键字volatile和synchronized,否则将存在线程非安全的问题。
public static synchronized LazySingleton getInstance()
{
//getInstance 方法前加同步
if(instance==null)
{
instance=new LazySingleton();
}
return instance;
}

}

6.3 饿汉式(写死静态对象 线程安全 立即加载)

一旦加载就会创建一个单例,保证在调用getInstance方法之前单例就已经存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HungrySingleton
{
//饿汉式单例在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变
//所以是线程安全的,可以直接用于多线程而不会出现问题。
private static final HungrySingleton instance=new HungrySingleton();
private HungrySingleton(){

}

public static HungrySingleton getInstance()
{
return instance; //之前写死了一个instance
}

}

6.4 单例模式应用场景

1. 其类只需要生成一个对象 比如一个班的班长 每个人的身份证号
2. 当对象需要被共享的场合,由于只能创建一个对象,所以共享比较节省内存 比如web的配置对象,数据库连接池
3. 当某类需要频繁实例化,而创建的对象又频繁被销毁 如多线程的线程池、网络连接池
4. Windows 的回收站、操作系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象    

7.原型模式(实现Cloneable接口的clone()方法)

7.1 定义和特点

1. 定义:
    1.1 在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效
    1.2 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。

2. 特点:
    2.1 无需知道对象创建的细节

7.2 深克隆

浅克隆不会克隆原对象中的引用类型,仅仅拷贝了引用类型的指向。深克隆则拷贝了所有。也就是说深克隆能够做到原对象和新对象之间完全没有影响。

引用类型所在的类实现Cloneable接口,并使用public修饰符重写clone方法

7.3 浅克隆

具体原型类只要实现Cloneable接口就可实现对象的浅克隆(Cloneable接口是抽象原型类)

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

//具体原型类
class Realizetype implements Cloneable //实现Cloneable接口
{
Realizetype(){
System.out.println("具体原型创建成功!"); //构造函数
}
public Object clone() throws CloneNotSupportedException{ //重写clone方法
System.out.println("具体原型复制成功!");
return (Realizetype)super.clone();
}
}

//原型模式的测试类
public class PrototypeTest
{
public static void main(String[] args)throws CloneNotSupportedException{
Realizetype obj1=new Realizetype();
Realizetype obj2=(Realizetype)obj1.clone(); //obj2复制obj1
System.out.println(obj1==obj2);
}
}


//输出结果
具体原型创建成功!
具体原型复制成功!
false

7.4 原型模式应用场景

1. 对象之间相同/相似
2. 对象创建比较麻烦,但复制比较简单

8.工厂方法模式(满足开闭原则的可以拓展,不能修改)

8.1 定义和特点

1. 定义:
    一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类中。
    (我定义一个模型样子,具体怎么搞看你子类生产了)
2. 产品: 被创建的对象
3. 工厂: 创建产品的对象

4. 特点:
    4.1 用户只需要知道具体工厂名称就可以得到产品(无须知道产品的具体创建过程)
    4.2 不需要对原厂进行修改,只需要在添加新产品的时候添加具体产品类和对应具体工厂类(符合开闭原则:可以拓展不可以修改)
    4.3 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度

8.2 结构

8.3 举例(设计畜牧场)

8.4 工厂方法模式应用场景

1. 客户只知道创建产品的工厂名(不知道具体的产品名)  如TCL电视工厂、海信电视工厂
2. 创建对象的任务由多个具体子工厂中的某一个完成
3. 抽象工厂只提供创建产品的接口
4. 客户只关心产品的名牌(细节无所谓)

9.抽象工厂模式(多等级产品的生产)

9.1 定义和特点

1. 定义
    1.1 为访问类提供一个创建一组相关或相互依赖对象的接口
    1.2 且访问类不需要指定所要产品具体类就能得到同族的不同等级的产品的模式结构。

2. 特点
    2.1 可生产多个等级的产品
    2.2 当增加一个新产品族时不需修改原代码(满足开闭原则)
    2.3 当产品族增加一个新产品时,所有工厂类都要修改

9.2 结构

9.3 举例(设计农场类)

9.4 抽象工厂模式应用场景

1. 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
2. 系统有多个产品族,但每次只用一族(有人只穿某个品牌衣服鞋)
3. 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

10.建造者模式

10.1 定义和特点

1. 定义:
    将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示

2. 特点:
    2.1 各建造者相互独立,有利于系统扩展
    2.2 客户端不需要知道产品内部组成细节,便于控制细节风险
    2.3 关注零部件的组装过程(工厂方法模式更关注零部件创建过程)

10.2 结构

Product产品类

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

class Product{
//三个参数
private String partA;
private String partB;
private String partC;
//三个set方法
public void setPartA(String partA)
{
this.partA=partA;
}
public void setPartB(String partB)
{
this.partB=partB;
}
public void setPartC(String partC)
{
this.partC=partC;
}
//show方法
public void show()
{
//显示产品的特性
}

}

Builder抽象建造者(接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14

abstract class Builder
{
//创建产品对象
protected Product product=new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult(){
return product;
}

}

ConcreteBuilder具体建造类(实现抽象建造者接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
 //继承Builder接口
public class ConcreteBuilder extends Builder
{
public void buildPartA(){
product.setPartA("建造 PartA");
}
public void buildPartB(){
product.setPartA("建造 PartB");
}
public void buildPartC(){
product.setPartA("建造 PartC");
}
}

Director指挥者(调用建造者方法完成复杂对象的创建)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Director
{
private Builder builder; //接口实例
public Director(Builder builder)
{
this.builder=builder; //构造函数
}
//产品构建与组装方法
public Product construct(){
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
}

}

客户端Client

1
2
3
4
5
6
7
8
9

public class Client{
public static void main(String[] args){
Builder builder=new ConcreteBuilder();
Director director=new Director(builder);
Product product=director.construct();
product.show();
}
}

10.3 举例(客厅装修)

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
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

//main方法类
public class ParlourDecorator
{
public static void main(String[] args)
{

Decorator d=(Decorator) ReadXML.getObject();
ProjectManager m=new ProjectManager(d); //指挥者
Parlour p=m.decorate(); //产品
p.show(); //调取结果
}
}

//产品:客厅
class Parlour
{
private String wall; //墙
private String TV; //电视
private String sofa; //沙发
public void setWall(String wall)
{
this.wall=wall;
}
public void setTV(String TV)
{
this.TV=TV;
}
public void setSofa(String sofa)
{
this.sofa=sofa;
}
public void show()
{
System.out.println(wall); //展示方法
System.out.println(tv);
System.out.println(sofa);
}

}

//抽象建造者:装修工人
abstract class Decorator
{
//创建产品对象
protected Parlour product=new Parlour();
public abstract void buildWall();
public abstract void buildTV();
public abstract void buildSofa();
//返回产品对象
public Parlour getResult()
{
return product;
}
}

//具体建造者: 具体装修工人1
class ConcreteDecorator1 extends Decorator{ //继承
public void buildWall()
{
product.setWall("w1"); //给属性赋值
}
public void buildTV()
{
product.setTV("TV1");
}
public void buildSofa()
{
product.setSofa("sf1");
}
}

//具体建造者: 具体装修工人2
class ConcreteDecorator2 extends Decorator{
public void buildWall()
{
product.setWall("w2"); //给属性赋值
}
public void buildTV()
{
product.setTV("TV2");
}
public void buildSofa()
{
product.setSofa("sf2");
}
}

//指挥者:项目经理
class ProjectManager{
private Decorator builder;
public ProjectManager(Decorator builder)
{
this.builder=builder; //构造函数
}
//产品构建与组装方法
public Parlour decorate(){
builder.buildWall(); //进行装修修饰(让具体工人去干活)
builder.buildTV();
builder.buildSofa();
return builder.getResult();
}
}

10.4 建造者模式应用场景

1. 对象较复杂 多个部件构成(部件间相对稳定)
2. 产品构建过程和最终表示是独立的

11.结构型模式(类和对象的布局结构)

11.1 分类(两大类七小类)

1. 类结构型模式  组织接口和类(继承的方式)
    1.1 适配器模式(Adapter) : 将一个类的接口A转换成客户希望的另外一个接口B,使得原来由于接口不兼容不能一起工作的类又能一起工作


2. 对象结构型模式 组合对象(组合/聚合的方式)
    2.1 代理模式(Proxy) : 为某对象提供一种代理用来控制对该对象的访问(修改对象的特性)
    2.2 适配器模式(Adapter) : 将一个类的接口A转换成客户希望的另外一个接口B,使得原来由于接口不兼容不能一起工作的类又能一起工作
    2.3 桥接模式(Bridge) : 抽象和现实分离(组合代替继承)
    2.4 装饰模式(Decorator) : 动态地给对象增加一些职能(增加额外功能) 
    2.5 外观模式(Facade) : 为多个复杂的子系统提供一个一致的接口(使子系统更容易被访问)
    2.6 享元模式(Flyweight) : 运用共享技术支持大量细粒度对象的复用
    2.7 组合模式(Composite) : 将对象组合成树状层次结构,让用户对单个对象和组合对象具有一致访问性

12.代理模式(中介)

12.1 定义和特点

1. 定义
    需要给某对象提供一个代理以控制对该对象的访问。
    访问对象不适合/不能直接引用目标对象(代理对象作为访问对象和目标对象的中介)

2. 特点
    2.1 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用
    2.2 代理对象可以扩展目标对象的功能
    2.3 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度
    2.4 但是,会增加系统的复杂度和请求处理速度变慢

12.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

//客户类(执行main方法)
public class ProxyTest{
public static void main(String[] args){
Proxy p=new Proxy(); //代理类生成对象
P.Request(); //调用真实主题里存在的方法
}
}

//抽象主题
interface Subject{
void Request(); //接口只写方法
}

//真实主题
public class RealSubject implements Subject{
public void Request(){
System.out.println("这是访问真实主题方法!!");
}
}

//代理
public class Proxy implements Subject{
private RealSubject realSubject; //生成真实主题对象
public void Request(){
if(realSubject==null){
realSubject=new RealSubject(); //为空新建
}
preRequest(); //调用代理新加的功能
realSubject.Request(); //调用原有方法
postRequest(); //调用代理新加的功能
}
//新加的功能
public void preRequest(){
System.out.println("访问真实主题预处理");
}
public void postRequest(){
System.out.println("访问真实主题后续处理");
}
}

//执行结果
访问真实主题预处理
访问真实主题方法...
访问真实主题后续处理

12.3 举例(原有类上更新功能)

12.4 代理模式应用场景

1. 以前的功能在不修改基础上/不可看到接口内部 -- 代理模式进行扩展和修改
2. 远程代理 : 用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
3. 安全代理 : 控制不同种类客户对真实对象的访问权限。
4. 延迟加载 : 指为了提高系统的性能,延迟对目标的加载。

13.适配器模式(Adapter – 接口兼容)

13.1 定义和特点

1. 定义:
    将一个类的接口A转换成客户希望的另外一个接口B,这样使原来由于接口不兼容而不能一起工作的类能一起工作

2. 特点:
    2.1 分为类结构型模式(耦合度更高,使用较少)和对象结构性模式
    2.2 复用现存的类,不需要修改源代码而重用现有的适配者类

13.2 结构

1. 类适配器模式: 适配器类 implement 当前系统业务接口 + 适配器类 extends 组件
2. 对象适配器模式: 适配器类 implement 当前系统业务接口 + 组件引入到适配器类(聚合)
3. 两种类型的区别:
    只是客户端和适配器类代码不同!!!    

类适配器模式

对象适配器模式

13.3 举例(模拟新能源汽车发动机)

13.4 适配器模式应用场景

1. 以前开发的系统存在满足新系统功能需求的类,但是其接口和新系统接口不一致
2. 使用第三方提供的组件,但是组件接口定义和自己要求定义不同

14.桥接模式(组合替换继承)

14.1 定义和特点

1. 定义:
    将抽象和显示分离,使他们可以独立变化(组合代替继承)        
2. 特点:
    2.1 抽象和实现分离,扩展能力强
    2.2 实现细节可以对客户透明

14.2 结构

14.3 举例(模拟女士皮包选购)

14.4 桥接模式应用场景

1. 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
2. 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
1. 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。

15.装饰模式(Decorator动态增加职能)

15.1 定义和特点

1. 定义:
    1.1 不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能
    1.2 相当于在左边具体构件实现抽象构件的这条路基础上,增加右边这条线(抽象装饰类调用实现原来的具体构件的方法完成基础工作,然后具体装饰类可以新增功能)        

2. 特点:
    2.1 采用装饰模式扩展对象的功能比采用继承更加灵活
    2.2 可以设计多个不同的具体装饰类,创造出多个不同行为的组合

15.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

//具体装饰类
public class DecoratorPattern{
public static void main(String[] args){
Component p=new ConcreteComponent();
p.operation();
Component d=new ConcreteDecorator(p);
d.operation();
}
}

//抽象构件角色
interface Component{
public void operation();
}

//具体构件角色
class ConcreteComponent implements Component{
public ConcreteComponent(){
System.out.println("创建具体构件角色");
}
public void operation(){
System.out.println("调用具体构件角色的方法operation()");
}
}

//抽象装饰角色
class Decorator implements Component{
private Component component;
public Decorator(Component component){
this.component=component;
}
public void operation(){
component.operation();
}
}

//具体装饰角色
class ConcreteDecorator extends Decorator
{
public ConcreteDecorator(Component component){
super(component);
}
public void operation(){
super.operation();
addedFunction();
}
//新增加的功能
public void addedFunction(){
System.out.println("为具体构件角色增加额外的功能addedFunction()");
}
}

//运行结果

创建具体构件角色
调用具体构件角色的方法operation()
调用具体构件角色的方法operation() //完成前面的功能
为具体构件角色增加额外的功能addedFunction() //新增功能

15.3 举例(美少女变身)

1. 其实本来就是茉莉卡原身实现茉莉卡接口进行display()方法展示
2. 但是现在我想变更多的样子我不想生成子类我就想使用装饰模式
3. 所以我新建changer变形类实现茉莉卡接口展示茉莉卡原身,然后生成新子类女巫和少女类不仅实现了茉莉卡方法展示茉莉卡原身,并且可以换新的setchanger()装备样子;

15.4 装饰模式应用场景

1. 需要给一个现有类添加附加只能,而且不能采用生成子类的方法扩充时候
2. 当对象的功能要求可以动态添加和删除

16.外观模式(提供统一接口)

16.1 定义和特点

1. 定义:
    通过为多个复杂子系统提供一致的接口

2. 特点:
    2.1 降低各子系统之间的耦合度
    2.2 降低了大型软件系统编译依赖性

16.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

//客户类
public class FacadePattern{
public static void main(String[] args){
Facade f=new Facade();
f.method(); //调用方法
}
}

//外观角色
class Facade{
private SubSystem01 obj1=new SubSystem01();
private SubSystem02 obj2=new SubSystem02();
private SubSystem03 obj3=new SubSystem03();
public void method(){ //调用三个子类
obj1.method1();
obj2.method2();
obj3.method3();
}
}

//子系统角色
class SubSystem01{
public void method1(){
System.out.println("子系统01的method1()被调用!");
}
}

//子系统角色
class SubSystem02{
public void method2(){
System.out.println("子系统02的method2()被调用!");
}
}

//子系统角色
class SubSystem03{
public void method3(){
System.out.println("子系统03的method3()被调用!");
}
}


//运行结果(客户来不会一个一个子系统调用,只会去找外观角色facade)

子系统01的method1()被调用!
子系统02的method2()被调用!
子系统03的method3()被调用!

16.3 举例(办理业务)

16.4 外观模式应用场景

1. 子系统很多,需要外观模式为系统设计一个简单的接口供外界访问。

17.享元模式(flyweight)

17.1 定义和特点

1. 定义:
    运用共享技术有效地支持大量细粒度对象的复用

2. 特点:
    2.1 为了使对象可以共享,需要将一些不能共享的状态外部化
    2.2 相同的对象只需要保存一份,降低系统中对象的数量

17.2 结构

17.3 举例(五子棋)

五子棋同围棋一样,包含多个“黑”或“白”颜色的棋子,
所以用享元模式比较好。

17.4 享元模式应用场景

1. 系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。
2. 大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态。
3. 由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才值得使用享元模式。

18.组合模式(部分-整体模式)

18.1 定义和特点

1. 定义:
    将对象组合成树状的层次结构,使用户对每个对象和组合对象具有一致的访问性

2. 特点:
    2.1 客户端代码可以一致地处理单个对象和组合对象
    2.2 更容易在组合体内加入新对象

18.2 结构

透明式

安全式

18.3 举例(购物显示各个商品)

18.4 组合模式应用场景

1. 需要表示一个对象整体与部分的层次结构场合

19.行为型模式(类/对象协同工作)

19.1 行为型模式分类(11个)

1. 模板方法模式(Template Method) 定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

2. 策略模式(Strategy) 定义一系列算法,并且将算法封装起来,相互替换。

3. 命令模式(Command) 将一个请求封装为一个对象,使发出请求和执行分开

4. 职责链模式(Chain of Responsibility) 将请求从链中的一个对象传到下一个对象,直到请求被响应为止

5. 状态模式(State) 允许一个对象在其内部状态发生改变时改变行为能力

6. 观察者模式(Observer) 多个对象间存在一对多关系,当一个对象改变,把这种改变通知给其他多个观察者,从而影响其他对象行为

7. 中介者模式(Mediator) 定义一个中介对象来简化原有对象之间的交互关系

8. 迭代器模式(Iterator) 提供一种方法来顺序访问聚合对象中的数据,而不暴露内部

9. 访问者模式(Visitor) 为一个集合中的每个元素提供多种访问方式

10. 备忘录模式(Memento) 不破坏封装,获取保存一个对象的内部状态,以便后面恢复

11. 解释器模式(Interpreter) 提供如何定义语言文法,以及对语言句子的解释方法

12. 模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式

20.观察者模式/发布订阅/模型视图(Observer模式连带改变)

20.1 定义和特点

1. 定义:(对象行为型模式)
    多个对象间存在一对多依赖,一个对象状态改变,所有依赖它的对象都得到通知并自动更新

2. 特点:    
    2.1 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
    2.2 目标与观察者之间建立了一套触发机制。
    2.3 观察者对象很多,通知的发布会花费很多时间,影响程序的效率。

20.2 结构

20.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
	//其实就是汇率抽象类让人民币汇率具体时间实现change()方法
//如果人民币汇率变化会通过company接口通知给实现接口的进出口公司

//人民币汇率执行类(main方法)
public class RMBrateTest{
public static void main(String[] args){
Rate rate=new RMBrate(); //新建汇率类
//新建两个实体公司
Company watcher1=new ImportCompany();
Company watcher2=new ExportCompany();
//汇率集合list添加两个公司和汇率改变
rate.add(watcher1);
rate.add(watcher2);
rate.change(10);
rate.change(-9);
}
}

//抽象目标:汇率
abstract class Rate{
protected List<Company> companys=new ArrayList<Company>();

//增加观察者方法
public void add(Company company){
companys.add(company); //添加公司(观察者)
}

//删除观察者方法
public void remove(Company company){
companys.remove(company);
}
//改变的方法 需要实现
public abstract void change(int number);

}

//具体目标:人民币汇率
class RMBrate extends Rate
{
public void change(int number){ //实现汇率类
for(Company obs:companys){
((Company)obs).response(number); //公司类改变汇率 (通知!!)
}
}
}

//抽象观察者:公司
interface Company{
void response(int number);
}

//具体观察者1:进口公司
class ImportCompany implements Company
{
public void response(int number){
if(number>0){
System.out.println("人民币汇率升值"+number+"个基点,降低了进口产品成本,提升了进口公司利润率。");
}
else if(number<0){
System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了进口产品成本,降低了进口公司利润率。");
}
}
}

//具体观察者2:出口公司
class ExportCompany implements Company {
public void response(int number){
if(number>0){
System.out.println("人民币汇率升值"+number+"个基点,降低了出口产品收入,降低了出口公司的销售利润率。");
}
else if(number<0){
System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了出口产品收入,提升了出口公司的销售利润率。");
}
}
}

20.4 应用场景

1. 对象间存在一对多关系,一个对象状态改变会影响其他对象
2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用

21.备忘录模式/快照模式(memento模式)

21.1 定义和特点

1. 定义:
    1.1 能记录一个对象的内部状态,当用户后悔时能撤销当前操作,使数据恢复到原先状态
    1.2 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。

2. 特点:    
    2.1 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地数据恢复到某个历史的状态。
    2.2 实现了内部状态的封装。除了创建它的发起人之外,其他对象都不能够访问这些状态信息。
    2.3 简化了发起人类。发起人不需要管理和保存其内部状态的各个备份,所有状态信息都保存在备忘录中,并由管理者进行管理,这符合单一职责原则。

21.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

//执行main方法类
public class MementoPattern{
public static void main(String[] args){
Originator or=new Originator(); //创建发起人
Caretaker cr=new Caretaker(); //创建管理者

or.setState("S0"); //发起人状态设置S0
System.out.println("初始状态:"+or.getState());

cr.setMemento(or.createMemento()); //管理者保存发起人状态
or.setState("S1"); //发起人更改状态为S1
System.out.println("新的状态:"+or.getState());

or.restoreMemento(cr.getMemento()); //发起人恢复状态为S0
System.out.println("恢复状态:"+or.getState());
}
}

//备忘录
class Memento{
private String state;
public Memento(String state){
this.state=state;
}
public void setState(String state){
this.state=state;
}
public String getState(){
return state; //获取状态state
}
}

//发起人
class Originator{
private String state;
public void setState(String state){
this.state=state;
}
public String getState(){
return state;
}
public Memento createMemento(){
return new Memento(state); //新建备忘录
}
public void restoreMemento(Memento m){
this.setState(m.getState()); //重新设置备忘录状态
}
}

//管理者
class Caretaker{
private Memento memento;
public void setMemento(Memento m){
memento=m; //设置备忘录
}
public Memento getMemento(){
return memento;
}
}

21.3 举例(相亲)

21.4 应用场景

1. 需要保存与恢复数据场景(玩游戏时存档功能)
2. 需要提供一个可回滚操作场景(Word、记事本、Photoshop,Eclipse软件Ctrl+Z、据库中事务操作)

22. 其余设计模式

其余设计模式均放入网站中可以浏览


×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 1.参考网址
  2. 2. 2.设计模式分类(三大类二十三种)
  3. 3. 3.统一建模语言(UML)
    1. 3.1. 3.1 类(类名、属性和操作之间有分割线的矩形)
    2. 3.2. 3.2 接口(带名称的小圆圈)
    3. 3.3. 3.3 类图(静态模型)
    4. 3.4. 3.4 类之间的关系(六个)
    5. 3.5. 3.5 参考文章
  4. 4. 4.UML设计七大原则
  5. 5. 5.创建型模式(怎样创建对象)
    1. 5.1. 5.1 创建型模式分类(五个)
  6. 6. 6.单例模式
    1. 6.1. 6.1 定义和特点
    2. 6.2. 6.2 懒汉式(每次访问都要同步 线程不安全 延迟加载)
    3. 6.3. 6.3 饿汉式(写死静态对象 线程安全 立即加载)
    4. 6.4. 6.4 单例模式应用场景
  7. 7. 7.原型模式(实现Cloneable接口的clone()方法)
    1. 7.1. 7.1 定义和特点
    2. 7.2. 7.2 深克隆
    3. 7.3. 7.3 浅克隆
    4. 7.4. 7.4 原型模式应用场景
  8. 8. 8.工厂方法模式(满足开闭原则的可以拓展,不能修改)
    1. 8.1. 8.1 定义和特点
    2. 8.2. 8.2 结构
    3. 8.3. 8.3 举例(设计畜牧场)
    4. 8.4. 8.4 工厂方法模式应用场景
  9. 9. 9.抽象工厂模式(多等级产品的生产)
    1. 9.1. 9.1 定义和特点
    2. 9.2. 9.2 结构
    3. 9.3. 9.3 举例(设计农场类)
    4. 9.4. 9.4 抽象工厂模式应用场景
  10. 10. 10.建造者模式
    1. 10.1. 10.1 定义和特点
    2. 10.2. 10.2 结构
    3. 10.3. 10.3 举例(客厅装修)
    4. 10.4. 10.4 建造者模式应用场景
  11. 11. 11.结构型模式(类和对象的布局结构)
    1. 11.1. 11.1 分类(两大类七小类)
  12. 12. 12.代理模式(中介)
    1. 12.1. 12.1 定义和特点
    2. 12.2. 12.2 结构
    3. 12.3. 12.3 举例(原有类上更新功能)
    4. 12.4. 12.4 代理模式应用场景
  13. 13. 13.适配器模式(Adapter – 接口兼容)
    1. 13.1. 13.1 定义和特点
    2. 13.2. 13.2 结构
    3. 13.3. 13.3 举例(模拟新能源汽车发动机)
    4. 13.4. 13.4 适配器模式应用场景
  14. 14. 14.桥接模式(组合替换继承)
    1. 14.1. 14.1 定义和特点
    2. 14.2. 14.2 结构
    3. 14.3. 14.3 举例(模拟女士皮包选购)
    4. 14.4. 14.4 桥接模式应用场景
  15. 15. 15.装饰模式(Decorator动态增加职能)
    1. 15.1. 15.1 定义和特点
    2. 15.2. 15.2 结构
    3. 15.3. 15.3 举例(美少女变身)
    4. 15.4. 15.4 装饰模式应用场景
  16. 16. 16.外观模式(提供统一接口)
    1. 16.1. 16.1 定义和特点
    2. 16.2. 16.2 结构
    3. 16.3. 16.3 举例(办理业务)
    4. 16.4. 16.4 外观模式应用场景
  17. 17. 17.享元模式(flyweight)
    1. 17.1. 17.1 定义和特点
    2. 17.2. 17.2 结构
    3. 17.3. 17.3 举例(五子棋)
    4. 17.4. 17.4 享元模式应用场景
  18. 18. 18.组合模式(部分-整体模式)
    1. 18.1. 18.1 定义和特点
    2. 18.2. 18.2 结构
    3. 18.3. 18.3 举例(购物显示各个商品)
    4. 18.4. 18.4 组合模式应用场景
  19. 19. 19.行为型模式(类/对象协同工作)
    1. 19.1. 19.1 行为型模式分类(11个)
  20. 20. 20.观察者模式/发布订阅/模型视图(Observer模式连带改变)
    1. 20.1. 20.1 定义和特点
    2. 20.2. 20.2 结构
    3. 20.3. 20.3 举例(人民币汇率对进出口公司调整)
    4. 20.4. 20.4 应用场景
  21. 21. 21.备忘录模式/快照模式(memento模式)
    1. 21.1. 21.1 定义和特点
    2. 21.2. 21.2 结构
    3. 21.3. 21.3 举例(相亲)
    4. 21.4. 21.4 应用场景
  22. 22. 22. 其余设计模式
,