设计模式整理完成2

This commit is contained in:
Estom
2021-04-11 14:27:41 +08:00
parent 9b657ef5c2
commit bf5e2c34f1
37 changed files with 351 additions and 299 deletions

View File

@@ -1,5 +1,16 @@
# 动态内存
> 存在的问题:栈空间和堆空间的分配也是运行时内存分配,即动态内存分配。文字常量区、全局变量和静态变量区是在编译时内存分配,即静态内存分配。
>
> 栈空间的动态内存分配由操作系统管理。堆空间的动态内存分配由用户自身管理。二者可以交叉使用。
>
> 例如:使用栈空间无法返回局部对象,只能返回局部对象的复制(重写复制构造函数),比较麻烦,可以返回堆空间申请一个对象,并返回指向该对象的指针。
>
> 例如使用堆空间对象的释放需要自己管理可以在栈空间创建一个局部对象在其内部封装申请和释放堆空间的方法。当栈空间的局部对象被销毁时调用析构函数清除堆空间的对象。这也是allocator和智能指针的实现方案。allocator一般使用栈对象的析构函数销毁堆对象的空间。智能指针一般通过引用计数的方法销毁堆对象。
>
> 关于汇编语言程序有两种方法进行动态分配:
> 方法一通过系统调用从操作系统获得内存块。linux/windows操作系统提供了alloc方法和heap方法。在当前的进程中后者用来申请新的私有堆前者用来在已有的堆空间上申请内存。
> 方法二:实现自己的堆管理器来服务更小的对象提出的请求。
## 0 C++直接管理内存
@@ -38,6 +49,16 @@ const int * pci = new const int(1024);
> 所有可变长度的容器都有自己的allcator实现动态内存管理不需要自己手动申请和释放内存。
### new和delete的工作机理
* 当我们使用new表达式分配内存时实际上执行了三个步骤。
1. 是调用名为operator new或者 operator new[])的标准库函数。该函数分配一块原始的足够大的未构造内存
2. 编译器运行构造函数构造对象
3. 返回一个指向该对象的指针
* 同样的delete则执行两个步骤:
1. 倒序执行对象的析构函数
2. 调用 operator delete或(operator delete[])标准库函数释放内存空间
## 1 动态内存与智能指针
> 所以智能指针使用过来做动态内存管理的。普通的局部变量及其指针不需要智能指针。智能指针是辅助new delete来管理动态内存的。智能指针就是为了解决一下问题。
@@ -163,7 +184,7 @@ if(shared_ptr<int>np = wp.lock()){
> * weak_ptr能将shared_ptr和weak_ptr赋值给weak_ptr;不能将新的动态内存对象赋值给智能指针。reset会将指针置为空。
## 4 动态数组
## 5 动态数组
### 初始化动态内存数组
```
@@ -210,3 +231,82 @@ alloc.deallocate(p,n)
* 标准库为allocator定义了两个伴随算法。
![](image/2021-03-06-22-42-35.png)
### allocator的简单实现
```C++
#ifndef __JJALLOC__
#define __JJALLOC__
#include<new> // for placement new
#include<iostream> //for cerr
#include<cstddef> //for ptrdiff_t
#include<cstdlib> // for exit()
#include<climits> // for UINT_MAX
namespace JJ{
template<class T>
inline T* _allocate(ptrdiff_t size, T*){
//set_new_handler(0);
T* tmp = (T*)(::operator new)((size_t)(size * sizeof(T)));
if (tmp == 0){
std::cerr << "out of memory" << std::endl;
}
return tmp;
}
template<class T>
inline void _destory(T* ptr){
ptr->~T();
}
template<class T>
inline void _deallocate(T* buffer){
::operator delete(buffer);
}
template<class T1,class T2>
inline void _construct(T1 *p, const T2 &value){
new(p)T1(value);
}
template <class T>
class allocate{
public:
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
typedef ptrdiff_t diference_type;
template<class U>
struct rebind{
typedef allocator<U> other;
};
pointer allocate(size_type n, const void * hint = 0){
return _allocate((difference_type)n, (pointer)0);
}
void deallocate(pointer p, size_type n){
_deallocate(p);
}
void construct(pointer p, const_reference value){
return _construct(p, value);
}
void destroy(pointer p){
_destroy(p);
}
pointer address(reference x){
return (pointer)&x;
}
pointer const_address(const_reference x){
return (const_pointer)&x;
}
size_type max_size()const{
return (size_type)(UINT_MAX / sizeof(T));
}
};
}
```

View File

@@ -57,7 +57,7 @@
* 目标代码生成与优化:代码生成器将中间代码转成机器代码,这个过程是依赖于目标机器的,因为不同的机器有着不同的字长、寄存器、数据类型等。最后目标代码优化器对目标代码进行优化,比如选择合适的寻址方式、使用唯一来代替乘除法、删除出多余的指令等。
三、汇编
## 3 汇编
汇编过程调用汇编器as来完成是用于将汇编代码转换成机器可以执行的指令每一个汇编语句几乎都对应一条机器指令。

View File

@@ -42,4 +42,50 @@ int main() {
strcpy(p1, "123456"); // 123456\0放在常量区编译器可能将它与p3所指向的"123456"优化成一个地方
return 0;
}
```
```
## 2 关于栈和堆的内存分配与编译执行过程的再说明
### 说明
1. **“编译器申请和释放栈内存空间”** 并不是说,在编译阶段就完成了内存空间的申请和释放,而是在编译阶段生成了**内存申请和释放的命令**。通过这些内存申请释放的机器指令,在执行阶段具体地完成内存的申请和释放。编译器负责生成这些命令,所以是编译器负责栈空间的管理。
2. “栈”是一种数据结构,通过机器指令实现,而不是一种内存空间结构。通过生成的指令,操作具体的地址,移动地址的指针,实现栈的计算。
3. 所以在编译阶段到底做了什么呢?当然是
1. **编译器自动生成了栈空间的申请和释放的机器指令,将指令的对象翻译为相对地址,实现栈的逻辑结构**
2. **用户实现了堆空间申请和释放的代码,编译器负责翻译为机器指令。但是没有相对地址,只有相对地址的指针**
4. 在实行阶段,将程序装入内存,对相对地址进行重定位。执行过程中,完成栈和堆的空间分配操作。
### 关于一个典型问题的说明
```
#include<iostream>
using namespace std;
int main(){
int n=1;
cin>>n;
int a=0;
//编译器提示数组的长度必须是常量(即编译器能够推断出数组的地址)
// 但是,编译器好像并没有报错而是采用了动态重定位的方式解决了运行时才能确定的数组的长度。
// 反正用vector就不会出现这些问题了因为他们的空间都是在堆上分配的。
int b[n];
int c=0;
cout<<&a<<" "<<&b<<" "<<&c<<endl;
cin>>c;
return 0;
}
```
* 问题描述如果在编译时进行内存分配那么n、a、c的相对地址应该都是确定的但是a的长度只能在运行时确定那么a和c在编译的时候相对地址到底是多少呢
* 解决方案在《操作系统》中介绍重定位主要有两种方式静态重定位装入的时候进行重定位。动态重定位执行过程中进行重定位。使用动态重定位在执行到int a[n]的时候对c进行动态重定位那么就可以解决问题了。这么说现在主流的操作系统、编译器都是动态重定位吗大概是吧。
* intelligence提示不能使用变量初始化数组的长度因为编译器无法确定相对地址。但是实际编译过程中并不会报错貌似是编译器采用了动态重定位技术或者其他的方法。对于这种问题一般有两种解决方法
* 让编译器自己解决(虽然提示不可以,但是编译器动态重定位的话应该行)
* 使用动态内存分配。malloc、new在堆上分配空间就不会出问题。
* 使用vector本身就是在堆上分配空间。
### 相关章节
* 编译原理
* 操作系统---内存管理---程序的装入与链接---重定位
* C++---标准库---动态内存管理---new、delete
* C++---面试---C++编译过程详解、C++内存分配

17
C++/面试/5.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include<iostream>
using namespace std;
int main(){
int n=1;
cin>>n;
int a=0;
//编译器提示数组的长度必须是常量(即编译器能够推断出数组的地址)
// 但是,编译器好像并没有报错而是采用了动态重定位的方式解决了运行时才能确定的数组的长度。
// 反正用vector就不会出现这些问题了因为他们的空间都是在堆上分配的。
int b[n];
int c=0;
cout<<&a<<" "<<&b<<" "<<&c<<endl;
cin>>c;
return 0;
}

View File

@@ -1,6 +1,6 @@
## 计划
- [ ] 设计模式复习
- [x] 设计模式复习
- [ ] vscode C++集成开发环境
- [ ] cmake/vs 项目重构
- [ ] 制定四月份论文阅读计划

View File

@@ -70,7 +70,7 @@
* 投递
- [x] 简历投递
- [x] 素质测评
- [ ] 2021年04月09日 19:00 - 2021年04月09日 20:00
- [x] 2021年04月09日 19:00 - 2021年04月09日 20:00
> 二期简历

View File

@@ -359,7 +359,8 @@ secondName
这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/40c0c17e-bba6-4493-9857-147c0044a018.png"/> </div><br>
![](image/2021-04-10-15-34-10.png)
### Implementation
@@ -442,7 +443,7 @@ public class Client {
下图中Factory 有一个 doSomething() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png"/> </div><br>
![](image/2021-04-10-15-32-27.png)
### Implementation
@@ -506,7 +507,8 @@ public class ConcreteFactory2 extends Factory {
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory而工厂方法模式使用了继承。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e2190c36-8b27-4690-bde5-9911020a1294.png"/> </div><br>
![](image/2021-04-10-15-26-15.png)
### Implementation
@@ -596,7 +598,8 @@ public class Client {
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/db5e376d-0b3e-490e-a43a-3231914b6668.png"/> </div><br>
![](image/2021-04-10-15-39-40.png)
### Implementation
@@ -686,7 +689,7 @@ abcdefghijklmnopqrstuvwxyz
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b8922f8c-95e6-4187-be85-572a509afb71.png"/> </div><br>
![](image/2021-04-10-15-44-20.png)
### Implementation
@@ -747,7 +750,7 @@ abc
- Handler定义处理请求的接口并且实现后继链successor
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ca9f23bf-55a4-47b2-9534-a28e35397988.png"/> </div><br>
![](image/2021-04-10-15-45-13.png)
### Implementation
@@ -885,13 +888,13 @@ request2 is handle by ConcreteHandler2
- Invoker通过它来调用命令
- Client可以设置命令与命令的接收者
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c44a0342-f405-4f17-b750-e27cf4aadde2.png"/> </div><br>
![](image/2021-04-10-15-36-32.png)
### Implementation
设计一个遥控器,可以控制电灯开关。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg"/> </div><br>
![](image/2021-04-11-10-24-34.png)
```java
public interface Command {
@@ -1006,7 +1009,8 @@ public class Client {
- TerminalExpression终结符表达式每个终结符都需要一个 TerminalExpression。
- Context上下文包含解释器之外的一些全局信息。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2b125bcd-1b36-43be-9b78-d90b076be549.png"/> </div><br>
![](image/2021-04-10-15-34-41.png)
### Implementation
@@ -1131,7 +1135,9 @@ false
- Iterator 主要定义了 hasNext() 和 next() 方法。
- Client 组合了 Aggregate为了迭代遍历 Aggregate也需要组合 Iterator。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/89292ae1-5f13-44dc-b508-3f035e80bf89.png"/> </div><br>
![](image/2021-04-10-15-29-46.png)
### Implementation
@@ -1220,17 +1226,17 @@ public class Client {
- Mediator中介者定义一个接口用于与各同事Colleague对象通信。
- Colleague同事相关对象
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png"/> </div><br>
![](image/2021-04-10-15-46-30.png)
### Implementation
Alarm闹钟、CoffeePot咖啡壶、Calendar日历、Sprinkler喷头是一组相关的对象在某个对象的事件产生时需要去操作其它对象形成了下面这种依赖结构
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg"/> </div><br>
![](image/2021-04-10-15-45-52.png)
使用中介者模式可以将复杂的依赖结构变成星形结构:
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg"/> </div><br>
![](image/2021-04-10-15-45-58.png)
```java
public abstract class Colleague {
@@ -1390,7 +1396,8 @@ doSprinkler()
- Caretaker负责保存好备忘录
- Menento备忘录存储原始对象的的状态。备忘录实际上有两个接口一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/50678f34-694f-45a4-91c6-34d985c83fee.png"/> </div><br>
![](image/2021-04-10-15-19-24.png)
### Implementation
@@ -1563,7 +1570,8 @@ public class Client {
主题Subject是被观察的对象而其所有依赖者Observer称为观察者。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg" width="600"/> </div><br>
![](image/2021-04-11-10-27-18.png)
### Class Diagram
@@ -1571,13 +1579,13 @@ public class Client {
观察者Observer的注册功能需要调用主题的 registerObserver() 方法。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/a8c8f894-a712-447c-9906-5caef6a016e3.png"/> </div><br>
![](image/2021-04-10-15-33-27.png)
### Implementation
天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg"/> </div><br>
![](image/2021-04-11-10-27-42.png)
```java
public interface Subject {
@@ -1698,13 +1706,13 @@ StatisticsDisplay.update: 1.0 1.0 1.0
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79df886f-fdc3-4020-a07f-c991bb58e0d8.png"/> </div><br>
![](image/2021-04-10-15-48-21.png)
### Implementation
糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg" width="600"/> </div><br>
![](image/2021-04-10-15-48-03.png)
```java
public interface State {
@@ -2005,7 +2013,7 @@ No gumball dispensed
- Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。
- Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior()setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png"/> </div><br>
![](image/2021-04-10-15-22-33.png)
### 与状态模式的比较
@@ -2092,13 +2100,14 @@ quack!
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ac6a794b-68c0-486c-902f-8d988eee5766.png"/> </div><br>
![](image/2021-04-10-15-37-47.png)
### Implementation
冲咖啡和冲茶都有类似的流程,但是某些步骤会有点不一样,要求复用那些相同步骤的代码。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/11236498-1417-46ce-a1b0-e10054256955.png"/> </div><br>
![](image/2021-04-11-10-29-38.png)
```java
public abstract class CaffeineBeverage {
@@ -2195,7 +2204,8 @@ Tea.addCondiments
- ConcreteVisitor具体访问者存储遍历过程中的累计结果
- ObjectStructure对象结构可以是组合结构或者是一个集合。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79c6f036-bde6-4393-85a3-ef36a0327bd2.png"/> </div><br>
![](image/2021-04-10-15-31-46.png)
### Implementation
@@ -2400,7 +2410,8 @@ Number of items: 6
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png"/> </div><br>
![](image/2021-04-10-15-35-35.png)
### Implementation
@@ -2452,11 +2463,12 @@ public class Client {
把一个类接口转换成另一个用户需要的接口。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png"/> </div><br>
![](image/2021-04-10-15-41-07.png)
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ff5152fc-4ff3-44c4-95d6-1061002c364a.png"/> </div><br>
![](image/2021-04-10-15-40-27.png)
### Implementation
@@ -2528,7 +2540,8 @@ public class Client {
- Abstraction定义抽象类的接口
- Implementor定义实现类接口
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png"/> </div><br>
![](image/2021-04-10-15-38-25.png)
### Implementation
@@ -2686,7 +2699,8 @@ public class Client {
组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png"/> </div><br>
![](image/2021-04-10-15-48-55.png)
### Implementation
@@ -2818,7 +2832,7 @@ Composite:root
装饰者Decorator和具体组件ConcreteComponent都继承自组件Component具体组件的方法实现不需要依赖于其它对象而装饰者组合了一个组件这样它可以装饰其它装饰者或者具体组件。所谓装饰就是把这个装饰者套在被装饰者之上从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的这属于它的功能然后调用被装饰者的方法实现从而也保留了被装饰者的功能。可以看到具体组件应当是装饰层次的最低层因为只有具体组件的方法实现不需要依赖于其它对象。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png"/> </div><br>
![](image/2021-04-10-15-47-29.png)
### Implementation
@@ -2826,7 +2840,8 @@ Composite:root
下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料,之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹Mocha 又被 Whip 包裹。它们都继承自相同父类,都有 cost() 方法,外层类的 cost() 方法调用了内层类的 cost() 方法。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg" width="600"/> </div><br>
![](image/2021-04-10-15-47-08.png)
```java
public interface Beverage {
@@ -2924,7 +2939,7 @@ public class Client {
### Class Diagram
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f9978fa6-9f49-4a0f-8540-02d269ac448f.png"/> </div><br>
![](image/2021-04-10-15-42-05.png)
### Implementation
@@ -2983,7 +2998,7 @@ public class Client {
- IntrinsicState内部状态享元对象共享内部状态
- ExtrinsicState外部状态每个享元对象的外部状态不同
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png"/> </div><br>
![](image/2021-04-10-15-43-43.png)
### Implementation
@@ -3072,7 +3087,10 @@ Java 利用缓存来加速大量小对象的访问时间。
- 保护代理Protection Proxy按权限控制对象的访问它负责检查调用者是否具有实现一个请求所必须的访问权限。
- 智能代理Smart Reference取代了简单的指针它在访问对象时执行一些附加操作记录对象的引用次数当第一次引用一个对象时将它装入内存在访问一个实际对象前检查是否已经锁定了它以确保其它对象不能改变它。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png"/> </div><br>
![](image/2021-04-10-15-28-02.png)
### Implementation

View File

@@ -1,88 +1,65 @@
设计模式之美:Creational Patterns创建型模式
# Creational Patterns创建型模式
创建型模式Creational Patterns抽象了对象实例化过程。
## 1 概述
它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
### 目标
创建型模式Creational Patterns**抽象了对象实例化过程**。
- 一个类创建型模式使用继承改变被实例化的类
用于 **创建、组合和表示** 一个系统的所有对象
- 一个对象创建型模式将实例化委托给另一个对象
- 一个类创建型模式使用继承改变被实例化的类
- 一个对象创建型模式将实例化委托给另一个对象。
随着系统演化得越来越依赖于对象复合而不是类的继承,创建型模式变得更为重要。
在这些模式中,有两个不断出现的主旋律:
1. 它们都将关于该系统使用那些具体的类的信息封装起来。
2. 它们隐藏了这些类的实例是如何被创建和放在一起的。
**因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以及何时创建这些方面给予你很大的灵活性。**
> **因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以及何时创建这些方面给予你很大的灵活性。**
>
> **Consequently, the creational patterns give you a lot of flexibility in what gets created, who creates it, how it gets created, and when.**
**Consequently, the creational patterns give you a lot of flexibility in what
gets created, who creates it, how it gets created, and when.**
## 2 具体方法
### **Factory Method (工厂方法)**
- **Factory Method (工厂方法)**
- Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
- 定义一个用于创建目标对象的接口让子类决定实例化哪一个目标类。Factory Method 使一个类的实例化延迟到其子类。
- Define an interface for creating an object, but let subclasses decide
which class to instantiate. Factory Method lets a class defer
instantiation to subclasses.
### **Prototype (原型)**
- 定义一个用于创建目标对象的接口让子类决定实例化哪一个目标类。Factory
Method 使一个类的实例化延迟到其子类。
- Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
- **Prototype (原型)**
- 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- Specify the kinds of objects to create using a prototypical instance,
and create new objects by copying this prototype.
### **Abstract Factory (抽象工厂)**
- 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
- **Abstract Factory (抽象工厂)**
- 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.
### **Builder (生成器)**
- 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- Separate the construction of a complex object from its representation so that the same construction process can create different representations.
- **Builder (生成器)**
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- Separate the construction of a complex object from its representation so
that the same construction process can create different representations.
### **Singleton (单件)**
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- Ensure a class only has one instance, and provide a global point of access to it.
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
- **Singleton (单件)**
- Ensure a class only has one instance, and provide a global point of
access to it.
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
用一个系统创建的那些对象的类对系统进行参数化有两种方法。
**方法一生成创建对象的类的子类Subclass这对应于使用 Factory Method
模式。**
这种方法的缺点是,仅为了改变产品类,就可能需要创建一个新的子类。这样的改变可能是级联的。
**方法二对系统进行参数化的方法依赖于对象复合Composition定义一个对象负责明确产品对象的类并将它作为该系统的参数。**
这是 Abstract Factory、Builder、Prototype 模式的关键特征。
这三种模式都涉及到创建一个新的负责创建产品对象的“工厂对象”。
- Abstract Factory 由这个工厂对象产生多个类的对象。
- Builder 由这个工厂对象使用一个相对复杂的协议,逐步创建一个复杂产品。
- Prototype
由该工厂对象通过拷贝原型对象来创建产品对象。在这种情况下,因为原型负责返回产品对象,所以工厂对象和原型是同一个对象。
对**创建系统**进行参数化有两种方法:
* **方法一依赖于被创建对象的类的继承Subclass定义被创建类的子类并将它作为系统的参数** ;这对应于使用 Factory Method模式。这种方法的缺点是仅为了改变产品类就可能需要创建一个新的子类。这样的改变可能是级联的。
* **方法二依赖于对象复合Composition定义一个对象负责明确产品对象的类并将它作为该系统的参数。** 这是 Abstract Factory、Builder、Prototype 模式的关键特征。这三种模式都涉及到创建一个**负责创建产品对象**的“工厂对象”。
- Abstract Factory 由这个工厂对象产生多个类的对象。
- Builder 由这个工厂对象使用一个相对复杂的协议,逐步创建一个复杂产品。
- Prototype由该工厂对象通过拷贝原型对象来创建产品对象。在这种情况下因为原型负责返回产品对象所以工厂对象和原型是同一个对象
Factory Method 使一个设计可以定制且只略微有一些复杂。其他设计模式需要新的类,而
Factory Method 只需要一个新的操作。
使用 Abstract Factory、Builder、Prototype 的设计比使用 Factory Method
的设计更灵活,但它们也更加复杂。
使用 Abstract Factory、Builder、Prototype 的设计比使用 Factory Method的设计更灵活,但它们也更加复杂。
**通常,设计以使用 Factory Method
开始,并且当设计者发现需要更大的灵活性时,设计便会向其他创建型模式演化。**
**通常,设计以使用 Factory Method开始,并且当设计者发现需要更大的灵活性时,设计便会向其他创建型模式演化。**

View File

@@ -4,17 +4,11 @@
**意图**
定义一个用于创建目标对象的接口,让子类决定实例化哪一个目标类。
定义一个用于创建目标对象的接口,让子类决定实例化哪一个目标类。Factory Method 使一个类的实例化延迟到其子类。
Factory Method 使一个类的实例化延迟到其子类。
Define an interface for creating an object, but let subclasses decide which
class to instantiate.
Factory Method lets a class defer instantiation to subclasses.
Define an interface for creating an object, but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
**结构**
![](image/2021-04-10-15-32-27.png)
![956473094863.png](media/2270a94077e069568d686166f5101fc9.png)

View File

@@ -17,8 +17,6 @@
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory而工厂方法模式使用了继承。
![](image/2021-04-10-15-26-15.png)
![126081935533.png](media/abc2df6bb6578e6901711922fb704575.png)
### **参与者**

View File

@@ -3,7 +3,7 @@
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
**结构**
![](image/2021-04-10-15-39-40.png)
![215216159109.png](media/ebed27694b48db7da45d4f8a573d1001.png)
**参与者**

View File

@@ -11,7 +11,7 @@ Specify the kinds of objects to create using a prototypical instance, and create
new objects by copying this prototype.
**结构**
![](image/2021-04-10-15-44-20.png)
![049306316682.png](media/034ce7ebd324d04b21ef2ba935649ff9.png)
**参与者**

View File

@@ -1,128 +1,85 @@
设计模式之美:Structural Patterns结构型模式
# Structural Patterns结构型模式
## 1 概述
### 目标
结构型模式涉及到如何组合类和对象以获得更大的结构。
- 结构型类模式采用继承机制来组合接口实现。
- 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。
- 结构型类模式采用继承机制来组合接口实现。
- 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法。
因为可以在运行时改变对象组合关系,所以对象组合方式具有更大的灵活性,而这种机制用静态组合是不可能实现的。
- **Adapter适配器**
### **Adapter适配器**
- 将一个类的接口转换成客户希望的另外一个接口。
- 将一个类的接口转换成客户希望的另外一个接口。
- Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- Convert the interface of a class into another interface clients expect.
### **Bridge桥接**
- Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
- 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- **Bridge桥接**
- 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
### **Composite组合**
- Decouple an abstraction from its implementation so that the two can vary
independently.
- 将对象组合成树形结构以表示 “部分-整体” 的层次结构。
- **Composite(组合)**
- Composite 使得用户对于单个对象和组合对象的使用具有一致性。
- 将对象组合成树形结构以表示 “部分-整体” 的层次结构。
- Composite 使得用户对于单个对象和组合对象的使用具有一致性。
### **Decorator装饰**
- Compose objects into tree structures to represent part-whole
hierarchies.
- 动态地给一个对象添加一些额外的职责。
- 就增加功能来说Decorator 模式相比生成子类更为灵活。
- Composite lets clients treat individual objects and compositions of
objects uniformly.
### **Facade外观**
- **Decorator装饰**
- 为子系统中的一组接口提供一个一致的界面。
- 动态地给一个对象添加一些额外的职责
- Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
- 就增加功能来说Decorator 模式相比生成子类更为灵活。
### **Flyweight享元**
- Attach additional responsibilities to an object dynamically.
- 运用共享技术有效地支持大量细粒度的对象。
- Decorators provide a flexible alternative to subclassing for extending
functionality.
- **Facade外观**
### **Proxy代理**
- 为子系统中的一组接口提供一个一致的界面
- 为其他对象提供一种代理以控制对这个对象的访问
- Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- Provide a unified interface to a set of interfaces in a subsystem.
- Facade defines a higher-level interface that makes the subsystem easier
to use.
- **Flyweight享元**
- 运用共享技术有效地支持大量细粒度的对象。
- Use sharing to support large numbers of fine-grained objects
efficiently.
- **Proxy代理**
- 为其他对象提供一种代理以控制对这个对象的访问。
- Provide a surrogate or placeholder for another object to control access
to it.
## 2 对比
### 相似性
结构型模式之间存在很多相似性,尤其是它们的参与者和协作之间的相似性。
这是因为结构型模式依赖于同一个很小的语言机制集合构造代码和对象:
- 单继承和多重继承机制用于基于类的模式。
- 单继承和多重继承机制用于基于类的模式。
- 对象组合机制用于对象式模式。
- 对象组合机制用于对象式模式。
### **Adapter 和 Bridge 的相似性**
**Adapter 和 Bridge 的相似性**
Adapter 模式和 Bridge模式具有一些共同的特征。它们之间的不同之处主要在于它们各自的用途。
* Adapter模式主要是为了解决两个已有接口之间不匹配的问题。它不考虑这些接口时怎么实现的也不考虑它们各自可能会如何演化。
* Bridge 模式则对抽象接口和它的实现部分进行桥接。它为用户提供了一个稳定的接口。
* Adapter 模式和 Bridge 模式通常被用于软件生命周期的不同阶段。
* 当你发现两个不兼容的类必须同时工作时,就有必要使用 Adapter模式以避免代码重复。此处耦合不可见。
* 相反Bridge的使用者必须事先知道一个抽象将有多个实现部分并且抽象和实现两者是独立演化得。
Adapter 模式和 Bridge
模式具有一些共同的特征。它们之间的不同之处主要在于它们各自的用途。
### **Composite 和 Decorator 的相似性**
Adapter
模式主要是为了解决两个已有接口之间不匹配的问题。它不考虑这些接口时怎么实现的,也不考虑它们各自可能会如何演化
Composite 和 Decorator模式具有类似的结构图这说明它们都基于递归组合来组织可变数目的对象。
* Decorator旨在使你能够不需要生成子类即可给对象添加职责。这就避免了静态实现所有功能组合从而导致子类急剧增加
* Composite则有不同的目的它旨在构造类使多个相关的对象能够以统一的方式处理而多重对象可以被当作一个对象来处理。它重点不在于修饰而在于表示。
Bridge 模式则对抽象接口和它的实现部分进行桥接。它为用户提供了一个稳定的接口。
Adapter 模式和 Bridge 模式通常被用于软件生命周期的不同阶段。
当你发现两个不兼容的类必须同时工作时,就有必要使用 Adapter
模式,以避免代码重复。此处耦合不可见。
相反Bridge
的使用者必须事先知道:一个抽象将有多个实现部分,并且抽象和实现两者是独立演化得。
**Composite 和 Decorator 的相似性**
Composite 和 Decorator
模式具有类似的结构图,这说明它们都基于递归组合来组织可变数目的对象。
Decorator
旨在使你能够不需要生成子类即可给对象添加职责。这就避免了静态实现所有功能组合,从而导致子类急剧增加。
Composite
则有不同的目的,它旨在构造类,使多个相关的对象能够以统一的方式处理,而多重对象可以被当作一个对象来处理。它重点不在于修饰,而在于表示。
**Decorator 和 Proxy 的相似性**
### **Decorator 和 Proxy 的相似性**
Decorator 和 Proxy 模式描述了怎样为对象提供一定程度上的间接引用。
Decorator 和 Proxy
对象的实现部分都保留了指向另一个对象的指针,它们向这个对象发送请求。
Decorator 和 Proxy对象的实现部分都保留了指向另一个对象的指针,它们向这个对象发送请求。
同样,它们也具有不同的设计目的。
Proxy
不能动态地添加和分离性质,它也不是为递归组合而设计的。它的目的是,当直接访问一个实体不方便或不符合需要时,为这个实体提供一个替代者
在 Proxy 中,实体定义了关键功能,而 Proxy 提供对它的访问。
在 Decorator 中,组件仅提供了部分功能,而 Decorator 负责完成其他功能。
* Proxy不能动态地添加和分离性质,它也不是为递归组合而设计的。它的目的是,当直接访问一个实体不方便或不符合需要时,为这个实体提供一个替代者。
* 在 Proxy 中,实体定义了关键功能,而 Proxy 提供对它的访问
* 在 Decorator 中,组件仅提供了部分功能,而 Decorator 负责完成其他功能。

View File

@@ -7,8 +7,6 @@
将一个类的接口转换成客户希望的另外一个接口。
Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
![](image/2021-04-10-15-41-07.png)
**结构**
类适配器使用多重继承对一个接口与另一个接口进行匹配。
@@ -19,7 +17,6 @@ Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类
![006051933731.png](media/9bae3ff976c8470b1d6ae9e9768409e4.png)
![](image/2021-04-10-15-40-27.png)
**参与者**
Target

View File

@@ -12,7 +12,7 @@ Decouple an abstraction from its implementation so that the two can vary
independently.
**结构**
![](image/2021-04-10-15-38-25.png)
![242197409687.png](media/ee4a265f47725eacf53741680d262704.png)
**参与者**

View File

@@ -17,7 +17,6 @@ uniformly.
![120529122324.png](media/f2793f123ffd3e6517ffca83c3b4218e.png)
![](image/2021-04-10-15-48-55.png)
**参与者**
Component

View File

@@ -14,7 +14,7 @@ Decorators provide a flexible alternative to subclassing for extending
functionality.
**结构**
![](image/2021-04-10-15-47-29.png)
![225319129467.png](media/688b6a2cfb78ed1f0b1a37b98f116dc9.png)
**参与者**

View File

@@ -7,7 +7,6 @@ Provide a unified interface to a set of interfaces in a subsystem. Facade
defines a higher-level interface that makes the subsystem easier to use.
**结构**
![](image/2021-04-10-15-42-05.png)
![000329435265.png](media/d95ed5b46b2cab7212804a212475ebef.png)
**参与者**

View File

@@ -5,7 +5,7 @@
Use sharing to support large numbers of fine-grained objects efficiently.
**结构**
![](image/2021-04-10-15-43-43.png)
![135082566859.png](media/322c8a847832fc5d2385537079343d7c.png)
下面的对象图说明了如何共享 Flyweight

View File

@@ -19,8 +19,6 @@ Provide a surrogate or placeholder for another object to control access to it.
- 保护代理Protection Proxy按权限控制对象的访问它负责检查调用者是否具有实现一个请求所必须的访问权限。
- 智能代理Smart Reference取代了简单的指针它在访问对象时执行一些附加操作记录对象的引用次数当第一次引用一个对象时将它装入内存在访问一个实际对象前检查是否已经锁定了它以确保其它对象不能改变它。
![](image/2021-04-10-15-28-02.png)
![505114124457.png](media/c13421b53c7c2b2146d2198f7ac4f85b.png)
运行时一种可能的 Proxy 结构的对象图:

View File

@@ -1,119 +1,78 @@
行为型模式涉及到算法和对象间职责的分配。
# 行为型模式涉及到算法和对象间职责的分配。
## 1 概述
### 目标
行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。
这些模式刻划了在运行时难以跟踪的复杂的控制流。它们将你的注意力从控制流转移到对象间的联系方式上来。
- 行为类模式使用继承机制在类间分派行为。
- 行为类模式使用继承机制在类间分派行为。
- 行为对象模式使用对象复合而不是继承。描述一组对等的对象怎样相互协作以完成任一个对象都无法完成的任务。
- 行为对象模式使用对象复合而不是继承。描述一组对等的对象怎样相互协作以完成任一个对象都无法完成的任务。
## 2 **行为型模式**
**行为型模式**
### **Chain of Responsibility职责链**
- **Chain of Responsibility职责链**
- 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
- 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
- 将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它位置
- 将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它位置。
### **Command命令**
- Avoid coupling the sender of a request to its receiver by giving more
than one object a chance to handle the request.
- 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- Chain the receiving objects and pass the request along the chain until
an object handles it.
- **Command命令**
### **Interpreter解释器**
- 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作
- 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
- Encapsulate a request as an object, thereby letting you parameterize
clients with different requests, queue or log requests, and support
undoable operations.
### **Iterator迭代器**
- **Interpreter解释器**
- 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
- 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
### **Observer观察者**
- Given a language, define a represention for its grammar along with an
interpreter that uses the representation to interpret sentences in the
language.
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- **Iterator迭代器**
- 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
### **Mediator中介者**
- Provide a way to access the elements of an aggregate object sequentially
without exposing its underlying representation.
- 用一个中介对象来封装一系列的对象交互。
- **Observer观察者**
- 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- Define a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updated
automatically.
### **Memento备忘录**
- **Mediator中介者**
- 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
- 用一个中介对象来封装一系列的对象交互。
- 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
### **State状态**
- Define an object that encapsulates how a set of objects interact.
- 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
- Mediator promotes loose coupling by keeping objects from referring to
each other explicitly, and it lets you vary their interaction
independently.
### **Strategy策略**
- **Memento备忘录**
- 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。使得算法可独立于使用它的客户而变化。
- 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
- Without violating encapsulation, capture and externalize an object's
internal state so that the object can be restored to this state later.
### **Template Method模板方法**
- **State状态**
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
- 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
- Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
- Allow an object to alter its behavior when its internal state changes.
The object will appear to change its class.
- **Strategy策略**
### **Visitor访问者**
- 定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。使得算法可独立于使用它的客户而变化
- 表示一个作用于某对象结构中的各元素的操作
- Define a family of algorithms, encapsulate each one, and make them
interchangeable.
- Visitor 使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- Strategy lets the algorithm vary independently from clients that use it.
- **Template Method模板方法**
- 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
- Template Method
使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- Define the skeleton of an algorithm in an operation, deferring some
steps to subclasses.
- Template Method lets subclasses redefine certain steps of an algorithm
without changing the algorithm's structure.
- **Visitor访问者**
- 表示一个作用于某对象结构中的各元素的操作。
- Visitor 使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- Represent an operation to be performed on the elements of an object
structure.
- Visitor lets you define a new operation without changing the classes of
the elements on which it operates.
**封装变化**
## 3 说明
### **封装变化**
当一个程序的某些方面的特征经常发生改变时,行为型模式就定义一个封装这个方面的对象。
@@ -121,17 +80,17 @@
这些模式通常定义一个抽象类来描述这些封装变化的对象,并且通常该模式依赖这个对象来命名。
- 一个 Strategy 对象封装一个 Algorithm。
- 一个 Strategy 对象封装一个 Algorithm。
- 一个 State 对象封装一个与状态相关的行为。
- 一个 State 对象封装一个与状态相关的行为。
- 一个 Mediator 对象封装对象间的协议。
- 一个 Mediator 对象封装对象间的协议。
- 一个 Iterator 对象封装访问和遍历一个聚合对象中的各个构件的方法。
- 一个 Iterator 对象封装访问和遍历一个聚合对象中的各个构件的方法。
大多数模式有两种对象:封装该方面特征的新对象,和使用这些新的对象的已有对象。
**对象作为参数**
### **对象作为参数**
一些模式引入总是被用作参数的对象。例如一个 Visitor 对象是一个多态的 Accept
操作的参数。

View File

@@ -19,7 +19,6 @@ handles it.
![212009985862.png](media/dd67bc16239c21383f68dac90175918b.png)
![](image/2021-04-10-15-45-13.png)
**参与者**
Handler

View File

@@ -6,7 +6,6 @@
Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
**结构**
![](image/2021-04-10-15-37-47.png)
![618336243562.png](media/62502293d8ec3c5ee0cb6130ba088ad9.png)
**参与者**
@@ -50,6 +49,7 @@ ConcreteClass
冲咖啡和冲茶都有类似的流程,但是某些步骤会有点不一样,要求复用那些相同步骤的代码。
![](image/2021-04-11-10-29-38.png)
```java
public abstract class CaffeineBeverage {

View File

@@ -12,7 +12,6 @@ elements on which it operates.
**结构**
![](image/2021-04-10-15-31-46.png)
![659484684950.png](media/2b90215e2319cee7220018f7e74ac572.png)

View File

@@ -9,7 +9,7 @@ that offers suitable default do nothing behavior.
In short, a design where "nothing will come of nothing".
**结构**
![](image/2021-04-10-15-35-35.png)
![352014475871.png](media/449673a26c6c7fbe0fe391c24734c75a.png)
**参与者**

View File

@@ -12,7 +12,7 @@ Encapsulate a request as an object, thereby letting you parameterize clients
with different requests, queue or log requests, and support undoable operations.
**结构**
![](image/2021-04-10-15-36-32.png)
![315146708441.png](media/31e9acd8d4ae264b538586670f9ffed9.png)
**参与者**

View File

@@ -6,7 +6,7 @@ Given a language, define a represention for its grammar along with an
interpreter that uses the representation to interpret sentences in the language.
**结构**
![](image/2021-04-10-15-34-41.png)
![152516715319.png](media/a6c50fe1fcfff1a376d34e0af97ace54.png)
**参与者**

View File

@@ -7,7 +7,6 @@
### **结构**
![](image/2021-04-10-15-29-46.png)
![207254216383.png](media/2b415d88952f47d7d4cd707cbc009287.png)

View File

@@ -10,7 +10,6 @@ Mediator promotes loose coupling by keeping objects from referring to each other
explicitly, and it lets you vary their interaction independently.
**结构**
![](image/2021-04-10-15-46-30.png)
![217545939801.png](media/7425d22312c40949be9309f07a4f5078.png)

View File

@@ -7,8 +7,6 @@
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
**结构**
![](image/2021-04-10-15-19-24.png)
![229273589556.png](media/5870f1e66b4dba9e3f59dcd29cf0f8bd.png)
**参与者**

View File

@@ -10,7 +10,6 @@
**结构**
![](image/2021-04-10-15-33-27.png)
![244171718081.png](media/7f6de13b5ce6b6c8c6ed6422472d1c32.png)
@@ -69,7 +68,7 @@ ConcreteObserver
天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg"/> </div><br>
![](image/2021-04-11-10-27-42.png)
```java
public interface Subject {

View File

@@ -4,7 +4,7 @@
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
**结构**
![](image/2021-04-10-15-48-21.png)
![547252187237.png](media/de271ae3dd89c9f862ae1b16714ff5db.png)
**参与者**

View File

@@ -10,7 +10,7 @@
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。使得算法可独立于使用它的客户而变化。
### **结构**
![](image/2021-04-10-15-22-33.png)
![559166861981.png](media/28cabe60fc8136de5c80e251000dd2ee.png)
### **参与者**

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB