Compare commits
19
Commits
443e4f2352
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a692b5361b | ||
|
|
7572425590 | ||
|
|
c52431fb9d | ||
|
|
4b2053c0f9 | ||
|
|
b6f0ca5aef | ||
|
|
a319494128 | ||
|
|
e5be1b62c2 | ||
|
|
5fbbada4b7 | ||
|
|
5ddda4ee95 | ||
|
|
5022b481a4 | ||
|
|
78d4634cf3 | ||
|
|
f579b1a5cc | ||
|
|
cc215c9d70 | ||
|
|
3a23a4d95a | ||
|
|
feaa733595 | ||
|
|
9bb30b8bfb | ||
|
|
232b926a97 | ||
|
|
4589debb92 | ||
|
|
4f8d653153 |
@@ -0,0 +1,219 @@
|
|||||||
|
# Design Patterns Implementation
|
||||||
|
|
||||||
|
[中文版 README](README_CN.md) | This repository contains implementations of the 23 classic Gang of Four (GoF) design patterns in three different programming languages: Go, TypeScript, and Python. Each pattern is implemented with clear examples and explanations to help developers understand and apply these fundamental design principles.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [Design Patterns Overview](#design-patterns-overview)
|
||||||
|
- [Project Structure](#project-structure)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Design patterns are typical solutions to commonly occurring problems in software design. They represent best practices that seasoned object-oriented software developers have used in their work for decades. This repository provides practical implementations of these patterns in three popular programming languages to demonstrate their usage and benefits.
|
||||||
|
|
||||||
|
## Design Patterns Overview
|
||||||
|
|
||||||
|
This repository includes implementations of all 23 Gang of Four design patterns:
|
||||||
|
|
||||||
|
### Creational Patterns
|
||||||
|
- **Abstract Factory**: Provides an interface for creating families of related objects
|
||||||
|
- **Builder**: Separates the construction of a complex object from its representation
|
||||||
|
- **Factory Method**: Defines an interface for creating an object, but lets subclasses alter the type of objects that will be created
|
||||||
|
- **Prototype**: Specifies the kinds of objects to create using a prototypical instance
|
||||||
|
- **Singleton**: Ensures a class has only one instance and provides a global point of access to it
|
||||||
|
|
||||||
|
### Structural Patterns
|
||||||
|
- **Adapter**: Converts the interface of a class into another interface clients expect
|
||||||
|
- **Bridge**: Decouples an abstraction from its implementation so that the two can vary independently
|
||||||
|
- **Composite**: Composes objects into tree structures to represent part-whole hierarchies
|
||||||
|
- **Decorator**: Attaches additional responsibilities to an object dynamically
|
||||||
|
- **Facade**: Provides a unified interface to a set of interfaces in a subsystem
|
||||||
|
- **Flyweight**: Uses sharing to support large numbers of fine-grained objects efficiently
|
||||||
|
- **Proxy**: Provides a surrogate or placeholder for another object to control access to it
|
||||||
|
|
||||||
|
### Behavioral Patterns
|
||||||
|
- **Chain of Responsibility**: Passes a request along a chain of handlers
|
||||||
|
- **Command**: Encapsulates a request as an object
|
||||||
|
- **Interpreter**: Defines a grammatical representation for a language
|
||||||
|
- **Iterator**: Provides a way to access the elements of an aggregate object sequentially
|
||||||
|
- **Mediator**: Defines how a set of objects interact with each other
|
||||||
|
- **Memento**: Captures and externalizes an object's internal state without violating encapsulation
|
||||||
|
- **Observer**: Defines a one-to-many dependency between objects so that when one object changes state, all dependents are notified automatically
|
||||||
|
- **State**: Allows an object to alter its behavior when its internal state changes
|
||||||
|
- **Strategy**: Defines a family of algorithms, encapsulates each one, and makes them interchangeable
|
||||||
|
- **Template Method**: Defines the skeleton of an algorithm in an operation, deferring some steps to subclasses
|
||||||
|
- **Visitor**: Represents an operation to be performed on the elements of an object structure
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
design-patterns/
|
||||||
|
├── go/ # Go implementations
|
||||||
|
│ ├── abstract_factory/
|
||||||
|
│ ├── adapter/
|
||||||
|
│ ├── bridge/
|
||||||
|
│ ├── builder/
|
||||||
|
│ ├── chain_of_responsibility/
|
||||||
|
│ ├── command/
|
||||||
|
│ ├── composite/
|
||||||
|
│ ├── decorator/
|
||||||
|
│ ├── facade/
|
||||||
|
│ ├── factory_method/
|
||||||
|
│ ├── flyweight/
|
||||||
|
│ ├── interpreter/
|
||||||
|
│ ├── iterator/
|
||||||
|
│ ├── mediator/
|
||||||
|
│ ├── memento/
|
||||||
|
│ ├── observer/
|
||||||
|
│ ├── prototype/
|
||||||
|
│ ├── proxy/
|
||||||
|
│ ├── singleton/
|
||||||
|
│ ├── state/
|
||||||
|
│ ├── strategy/
|
||||||
|
│ ├── template_method/
|
||||||
|
│ ├── visitor/
|
||||||
|
│ ├── go.mod
|
||||||
|
│ ├── Makefile
|
||||||
|
│ └── README.md
|
||||||
|
├── python/ # Python implementations
|
||||||
|
│ ├── abstract_factory/
|
||||||
|
│ ├── adapter/
|
||||||
|
│ ├── bridge/
|
||||||
|
│ ├── builder/
|
||||||
|
│ ├── chain_of_responsibility/
|
||||||
|
│ ├── command/
|
||||||
|
│ ├── composite/
|
||||||
|
│ ├── decorator/
|
||||||
|
│ ├── facade/
|
||||||
|
│ ├── factory_method/
|
||||||
|
│ ├── flyweight/
|
||||||
|
│ ├── interpreter/
|
||||||
|
│ ├── iterator/
|
||||||
|
│ ├── mediator/
|
||||||
|
│ ├── memento/
|
||||||
|
│ ├── observer/
|
||||||
|
│ ├── prototype/
|
||||||
|
│ ├── proxy/
|
||||||
|
│ ├── singleton/
|
||||||
|
│ ├── state/
|
||||||
|
│ ├── strategy/
|
||||||
|
│ ├── template_method/
|
||||||
|
│ ├── visitor/
|
||||||
|
│ ├── Makefile
|
||||||
|
│ ├── pyproject.toml
|
||||||
|
│ └── README.md
|
||||||
|
├── ts/ # TypeScript implementations
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── abstract_factory/
|
||||||
|
│ │ ├── adapter/
|
||||||
|
│ │ ├── bridge/
|
||||||
|
│ │ ├── builder/
|
||||||
|
│ │ ├── chain_of_responsibility/
|
||||||
|
│ │ ├── command/
|
||||||
|
│ │ ├── composite/
|
||||||
|
│ │ ├── decorator/
|
||||||
|
│ │ ├── facade/
|
||||||
|
│ │ ├── factory_method/
|
||||||
|
│ │ ├── flyweight/
|
||||||
|
│ │ ├── interpreter/
|
||||||
|
│ │ ├── iterator/
|
||||||
|
│ │ ├── mediator/
|
||||||
|
│ │ ├── memento/
|
||||||
|
│ │ ├── observer/
|
||||||
|
│ │ ├── prototype/
|
||||||
|
│ │ ├── proxy/
|
||||||
|
│ │ ├── singleton/
|
||||||
|
│ │ ├── state/
|
||||||
|
│ │ ├── strategy/
|
||||||
|
│ │ ├── template_method/
|
||||||
|
│ │ ├── visitor/
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── pnpm-lock.yaml
|
||||||
|
│ ├── Makefile
|
||||||
|
│ └── README.md
|
||||||
|
├── .gitignore
|
||||||
|
├── README.md # This file
|
||||||
|
└── README_CN.md # Chinese version
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Go Implementation
|
||||||
|
|
||||||
|
1. Navigate to the Go directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd go
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run examples using:
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python Implementation
|
||||||
|
|
||||||
|
1. Navigate to the Python directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd python
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run examples using:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### TypeScript Implementation
|
||||||
|
|
||||||
|
1. Navigate to the TypeScript directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ts
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run examples using:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Here are some ways you can contribute:
|
||||||
|
|
||||||
|
1. Report bugs and issues
|
||||||
|
2. Suggest new features or improvements
|
||||||
|
3. Add implementations in other languages
|
||||||
|
4. Improve documentation
|
||||||
|
5. Add more comprehensive examples
|
||||||
|
|
||||||
|
To contribute:
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||||
|
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
||||||
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
||||||
|
5. Open a Pull Request
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License.
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
- The Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides) for their seminal work on design patterns
|
||||||
|
- The open-source community for providing inspiration and examples
|
||||||
|
- All contributors who help maintain and improve this repository
|
||||||
+220
@@ -0,0 +1,220 @@
|
|||||||
|
# 设计模式实现
|
||||||
|
|
||||||
|
本仓库包含了 23 种经典 GoF(Gang of Four)设计模式的三种编程语言实现:Go、TypeScript 和 Python。每种模式都提供了清晰的示例和解释,帮助开发者理解和应用这些基本的设计原则。
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
- [介绍](#介绍)
|
||||||
|
- [设计模式概览](#设计模式概览)
|
||||||
|
- [项目结构](#项目结构)
|
||||||
|
- [快速开始](#快速开始)
|
||||||
|
- [贡献](#贡献)
|
||||||
|
- [许可证](#许可证)
|
||||||
|
|
||||||
|
## 介绍
|
||||||
|
|
||||||
|
设计模式是软件设计中常见问题的典型解决方案。它们代表了经验丰富的面向对象软件开发人员在工作中使用的最佳实践。本仓库提供了这三种流行编程语言中的实用实现,以演示它们的用法和优势。
|
||||||
|
|
||||||
|
## 设计模式概览
|
||||||
|
|
||||||
|
本仓库包含所有 23 种 Gang of Four 设计模式的实现:
|
||||||
|
|
||||||
|
### 创建型模式
|
||||||
|
- **抽象工厂模式(Abstract Factory)**: 为创建相关对象族提供接口
|
||||||
|
- **建造者模式(Builder)**: 将复杂对象的构建与其表示分离
|
||||||
|
- **工厂方法模式(Factory Method)**: 定义创建对象的接口,但让子类决定将要创建的对象类型
|
||||||
|
- **原型模式(Prototype)**: 使用原型实例指定要创建的对象类型
|
||||||
|
- **单例模式(Singleton)**: 确保一个类只有一个实例,并提供全局访问点
|
||||||
|
|
||||||
|
### 结构型模式
|
||||||
|
- **适配器模式(Adapter)**: 将一个类的接口转换为客户期望的另一个接口
|
||||||
|
- **桥接模式(Bridge)**: 将抽象与其实现分离,使两者可以独立变化
|
||||||
|
- **组合模式(Composite)**: 将对象组合成树形结构以表示部分-整体层次结构
|
||||||
|
- **装饰器模式(Decorator)**: 动态地为对象附加额外职责
|
||||||
|
- **外观模式(Facade)**: 为子系统中的一组接口提供统一接口
|
||||||
|
- **享元模式(Flyweight)**: 使用共享来高效支持大量细粒度对象
|
||||||
|
- **代理模式(Proxy)**: 为另一个对象提供代理或占位符以控制对它的访问
|
||||||
|
|
||||||
|
### 行为型模式
|
||||||
|
- **责任链模式(Chain of Responsibility)**: 将请求沿处理程序链传递
|
||||||
|
- **命令模式(Command)**: 将请求封装为对象
|
||||||
|
- **解释器模式(Interpreter)**: 为语言定义语法表示
|
||||||
|
- **迭代器模式(Iterator)**: 提供一种方法来顺序访问聚合对象的元素
|
||||||
|
- **中介者模式(Mediator)**: 定义一组对象如何相互交互
|
||||||
|
- **备忘录模式(Memento)**: 在不违反封装的情况下捕获并外部化对象的内部状态
|
||||||
|
- **观察者模式(Observer)**: 定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会自动收到通知
|
||||||
|
- **状态模式(State)**: 允许对象在其内部状态改变时改变其行为
|
||||||
|
- **策略模式(Strategy)**: 定义算法族,封装每个算法,并使它们可互换
|
||||||
|
- **模板方法模式(Template Method)**: 在操作中定义算法骨架,将一些步骤推迟到子类
|
||||||
|
- **访问者模式(Visitor)**: 表示对对象结构中元素执行的操作
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
design-patterns/
|
||||||
|
├── go/ # Go 实现
|
||||||
|
│ ├── abstract_factory/
|
||||||
|
│ ├── adapter/
|
||||||
|
│ ├── bridge/
|
||||||
|
│ ├── builder/
|
||||||
|
│ ├── chain_of_responsibility/
|
||||||
|
│ ├── command/
|
||||||
|
│ ├── composite/
|
||||||
|
│ ├── decorator/
|
||||||
|
│ ├── facade/
|
||||||
|
│ ├── factory_method/
|
||||||
|
│ ├── flyweight/
|
||||||
|
│ ├── interpreter/
|
||||||
|
│ ├── iterator/
|
||||||
|
│ ├── mediator/
|
||||||
|
│ ├── memento/
|
||||||
|
│ ├── observer/
|
||||||
|
│ ├── prototype/
|
||||||
|
│ ├── proxy/
|
||||||
|
│ ├── singleton/
|
||||||
|
│ ├── state/
|
||||||
|
│ ├── strategy/
|
||||||
|
│ ├── template_method/
|
||||||
|
│ ├── visitor/
|
||||||
|
│ ├── go.mod
|
||||||
|
│ ├── Makefile
|
||||||
|
│ └── README.md
|
||||||
|
├── python/ # Python 实现
|
||||||
|
│ ├── abstract_factory/
|
||||||
|
│ ├── adapter/
|
||||||
|
│ ├── bridge/
|
||||||
|
│ ├── builder/
|
||||||
|
│ ├── chain_of_responsibility/
|
||||||
|
│ ├── command/
|
||||||
|
│ ├── composite/
|
||||||
|
│ ├── decorator/
|
||||||
|
│ ├── facade/
|
||||||
|
│ ├── factory_method/
|
||||||
|
│ ├── flyweight/
|
||||||
|
│ ├── interpreter/
|
||||||
|
│ ├── iterator/
|
||||||
|
│ ├── mediator/
|
||||||
|
│ ├── memento/
|
||||||
|
│ ├── observer/
|
||||||
|
│ ├── prototype/
|
||||||
|
│ ├── proxy/
|
||||||
|
│ ├── singleton/
|
||||||
|
│ ├── state/
|
||||||
|
│ ├── strategy/
|
||||||
|
│ ├── template_method/
|
||||||
|
│ ├── visitor/
|
||||||
|
│ ├── Makefile
|
||||||
|
│ ├── pyproject.toml
|
||||||
|
│ └── README.md
|
||||||
|
├── ts/ # TypeScript 实现
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── abstract_factory/
|
||||||
|
│ │ ├── adapter/
|
||||||
|
│ │ ├── bridge/
|
||||||
|
│ │ ├── builder/
|
||||||
|
│ │ ├── chain_of_responsibility/
|
||||||
|
│ │ ├── command/
|
||||||
|
│ │ ├── composite/
|
||||||
|
│ │ ├── decorator/
|
||||||
|
│ │ ├── facade/
|
||||||
|
│ │ ├── factory_method/
|
||||||
|
│ │ ├── flyweight/
|
||||||
|
│ │ ├── interpreter/
|
||||||
|
│ │ ├── iterator/
|
||||||
|
│ │ ├── mediator/
|
||||||
|
│ │ ├── memento/
|
||||||
|
│ │ ├── observer/
|
||||||
|
│ │ ├── prototype/
|
||||||
|
│ │ ├── proxy/
|
||||||
|
│ │ ├── singleton/
|
||||||
|
│ │ ├── state/
|
||||||
|
│ │ ├── strategy/
|
||||||
|
│ │ ├── template_method/
|
||||||
|
│ │ ├── visitor/
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── pnpm-lock.yaml
|
||||||
|
│ ├── Makefile
|
||||||
|
│ └── README.md
|
||||||
|
├── .gitignore
|
||||||
|
├── README.md # 英文版 README
|
||||||
|
└── README_CN.md # 中文版 README
|
||||||
|
```
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### Go 实现
|
||||||
|
|
||||||
|
1. 进入 Go 目录:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd go
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 运行示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python 实现
|
||||||
|
|
||||||
|
1. 进入 Python 目录:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd python
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 运行示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### TypeScript 实现
|
||||||
|
|
||||||
|
1. 进入 TypeScript 目录:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ts
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 安装依赖:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 运行示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
## 贡献
|
||||||
|
|
||||||
|
欢迎贡献!您可以通过以下方式参与:
|
||||||
|
|
||||||
|
1. 报告错误和问题
|
||||||
|
2. 建议新功能或改进
|
||||||
|
3. 添加其他语言的实现
|
||||||
|
4. 改进文档
|
||||||
|
5. 添加更全面的示例
|
||||||
|
|
||||||
|
贡献步骤:
|
||||||
|
|
||||||
|
1. Fork 仓库
|
||||||
|
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
|
||||||
|
3. 提交更改 (`git commit -m 'Add some amazing feature'`)
|
||||||
|
4. 推送到分支 (`git push origin feature/amazing-feature`)
|
||||||
|
5. 开启 Pull Request
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
本项目采用 MIT 许可证。
|
||||||
|
|
||||||
|
## 致谢
|
||||||
|
|
||||||
|
- Gang of Four(Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides)对设计模式的开创性工作
|
||||||
|
- 开源社区提供的灵感和示例
|
||||||
|
- 所有帮助维护和改进此仓库的贡献者
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝申请报销款,需要走产品经理、部门经理和总经理的审核~
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Manager struct {
|
||||||
|
name string
|
||||||
|
successor *Manager // successor表示下一级经理
|
||||||
|
amount float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetSuccessor(successor *Manager) {
|
||||||
|
m.successor = successor
|
||||||
|
fmt.Printf("%s的下一级经理是%s\n", m.name, successor.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) SetAmountRight(amount float64) {
|
||||||
|
m.amount = amount
|
||||||
|
fmt.Printf("%s的报销权限是%.2f元\n", m.name, amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) HaveRight(amount float64) bool {
|
||||||
|
|
||||||
|
if amount <= m.amount {
|
||||||
|
fmt.Printf("%s有权限审批%.2f元的报销请求\n", m.name, amount)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
fmt.Printf("%s没有权限审批%.2f元的报销请求\n", m.name, amount)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) Approve(name string, amount float64) {
|
||||||
|
fmt.Printf("%s提交了一笔%.2f元的报销请求\n", name, amount)
|
||||||
|
if m.HaveRight(amount) {
|
||||||
|
fmt.Printf("%s审批通过了%s的报销请求,金额为%.2f元\n", m.name, name, amount)
|
||||||
|
} else if m.successor != nil {
|
||||||
|
fmt.Printf("%s将%s的报销请求上报给%s审批\n", m.name, name, m.successor.name)
|
||||||
|
m.successor.Approve(name, amount)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("没有合适的经理审批%s的报销请求,金额为%.2f元\n", name, amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("========= 责任链模式 =========")
|
||||||
|
// 创建经理
|
||||||
|
pm := &Manager{name: "产品经理"}
|
||||||
|
pm.SetAmountRight(1000)
|
||||||
|
|
||||||
|
dm := &Manager{name: "部门经理"}
|
||||||
|
dm.SetAmountRight(5000)
|
||||||
|
|
||||||
|
gm := &Manager{name: "总经理"}
|
||||||
|
gm.SetAmountRight(20000)
|
||||||
|
|
||||||
|
// 设置责任链
|
||||||
|
pm.SetSuccessor(dm)
|
||||||
|
dm.SetSuccessor(gm)
|
||||||
|
|
||||||
|
// 提交报销请求
|
||||||
|
fmt.Println("-----")
|
||||||
|
pm.Approve("汤宝宝", 800)
|
||||||
|
fmt.Println("-----")
|
||||||
|
pm.Approve("汤宝宝", 3000)
|
||||||
|
fmt.Println("-----")
|
||||||
|
pm.Approve("汤宝宝", 15000)
|
||||||
|
fmt.Println("-----")
|
||||||
|
pm.Approve("汤宝宝", 25000)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("======= 责任链模式结束 =======")
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝成为一国之王,手下有一个传令官和三个大臣,分别是内政大臣、外交大臣和军事大臣。
|
||||||
|
有一天,汤宝宝想要发布一个命令,传令官负责将命令传达给大臣们,大臣们根据命令的内容决定是否执行。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 接收者接口
|
||||||
|
type Receiver interface {
|
||||||
|
perform()
|
||||||
|
abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内政大臣
|
||||||
|
type HomeSecretary struct {
|
||||||
|
isPerforming bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HomeSecretary) perform() {
|
||||||
|
h.isPerforming = true
|
||||||
|
fmt.Println("内政大臣开始执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HomeSecretary) abort() {
|
||||||
|
h.isPerforming = false
|
||||||
|
fmt.Println("内政大臣取消执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外交大臣
|
||||||
|
type ForeignSecretary struct {
|
||||||
|
isPerforming bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ForeignSecretary) perform() {
|
||||||
|
f.isPerforming = true
|
||||||
|
fmt.Println("外交大臣开始执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ForeignSecretary) abort() {
|
||||||
|
f.isPerforming = false
|
||||||
|
fmt.Println("外交大臣取消执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 军事大臣
|
||||||
|
type DefenseSecretary struct {
|
||||||
|
isPerforming bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DefenseSecretary) perform() {
|
||||||
|
d.isPerforming = true
|
||||||
|
fmt.Println("军事大臣开始执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DefenseSecretary) abort() {
|
||||||
|
d.isPerforming = false
|
||||||
|
fmt.Println("军事大臣取消执行命令")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令接口
|
||||||
|
type Command interface {
|
||||||
|
execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
type PerformCommand struct {
|
||||||
|
receiver Receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *PerformCommand) execute() {
|
||||||
|
c.receiver.perform()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消命令
|
||||||
|
type AbortCommand struct {
|
||||||
|
receiver Receiver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *AbortCommand) execute() {
|
||||||
|
c.receiver.abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoker - 传令官
|
||||||
|
type Herald struct {
|
||||||
|
commands []Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Herald) addCommand(command Command) {
|
||||||
|
h.commands = append(h.commands, command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Herald) executeCommands() {
|
||||||
|
for _, command := range h.commands {
|
||||||
|
command.execute()
|
||||||
|
}
|
||||||
|
h.commands = []Command{} // 清空命令列表
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("========= 命令模式 =========")
|
||||||
|
// 创建接收者
|
||||||
|
homeSecretary := &HomeSecretary{}
|
||||||
|
foreignSecretary := &ForeignSecretary{}
|
||||||
|
defenseSecretary := &DefenseSecretary{}
|
||||||
|
|
||||||
|
// 创建命令
|
||||||
|
performHomeCommand := &PerformCommand{receiver: homeSecretary}
|
||||||
|
abortHomeCommand := &AbortCommand{receiver: homeSecretary}
|
||||||
|
performForeignCommand := &PerformCommand{receiver: foreignSecretary}
|
||||||
|
abortForeignCommand := &AbortCommand{receiver: foreignSecretary}
|
||||||
|
performDefenseCommand := &PerformCommand{receiver: defenseSecretary}
|
||||||
|
abortDefenseCommand := &AbortCommand{receiver: defenseSecretary}
|
||||||
|
|
||||||
|
// 创建传令官
|
||||||
|
herald := &Herald{}
|
||||||
|
|
||||||
|
// 添加命令
|
||||||
|
herald.addCommand(performHomeCommand)
|
||||||
|
herald.addCommand(performForeignCommand)
|
||||||
|
herald.addCommand(performDefenseCommand)
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
herald.executeCommands()
|
||||||
|
|
||||||
|
// 取消命令
|
||||||
|
herald.addCommand(abortHomeCommand)
|
||||||
|
herald.addCommand(abortForeignCommand)
|
||||||
|
herald.addCommand(abortDefenseCommand)
|
||||||
|
|
||||||
|
// 执行取消命令
|
||||||
|
herald.executeCommands()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("======= 命令模式结束 =======")
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例
|
||||||
|
汤宝宝教你番茄炒蛋~
|
||||||
|
*/
|
||||||
|
|
||||||
|
type TomatoEgg struct{}
|
||||||
|
|
||||||
|
func (t *TomatoEgg) Serve() {
|
||||||
|
fmt.Println("番茄炒蛋上桌啦!")
|
||||||
|
}
|
||||||
|
|
||||||
|
type CutTomato struct{}
|
||||||
|
|
||||||
|
func (c *CutTomato) Cut() {
|
||||||
|
fmt.Println("番茄切好了。")
|
||||||
|
}
|
||||||
|
|
||||||
|
type BeatEgg struct{}
|
||||||
|
|
||||||
|
func (b *BeatEgg) Beat() {
|
||||||
|
fmt.Println("鸡蛋打散了。")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cook struct {
|
||||||
|
cutTomato *CutTomato
|
||||||
|
beatEgg *BeatEgg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cook) CookDish() {
|
||||||
|
c.cutTomato.Cut()
|
||||||
|
c.beatEgg.Beat()
|
||||||
|
fmt.Println("食材放入锅中,开火加热。")
|
||||||
|
fmt.Println("番茄炒蛋炒好了。")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外观
|
||||||
|
type ChefFacade struct {
|
||||||
|
cook *Cook
|
||||||
|
dish *TomatoEgg
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewChefFacade() *ChefFacade {
|
||||||
|
return &ChefFacade{
|
||||||
|
cook: &Cook{
|
||||||
|
cutTomato: &CutTomato{},
|
||||||
|
beatEgg: &BeatEgg{},
|
||||||
|
},
|
||||||
|
dish: &TomatoEgg{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChefFacade) PrepareAndServe() {
|
||||||
|
fmt.Println("准备食材...")
|
||||||
|
c.cook.CookDish()
|
||||||
|
c.dish.Serve()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 外观模式 =============")
|
||||||
|
|
||||||
|
chef := NewChefFacade()
|
||||||
|
chef.PrepareAndServe()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 外观模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝开了一家服装租赁店,好多客人来店里租衣服~
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 享元抽象类
|
||||||
|
type ClothingInterface interface {
|
||||||
|
Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 享元对象 - 服装
|
||||||
|
type Clothing struct {
|
||||||
|
style string
|
||||||
|
size string
|
||||||
|
color string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Clothing) Show() {
|
||||||
|
fmt.Printf("服装款式:%s,尺码:%s,颜色:%s\n", c.style, c.size, c.color)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 享元工厂 - 服装店
|
||||||
|
type ClothingFactory struct {
|
||||||
|
clothingPool map[string]ClothingInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClothingFactory() *ClothingFactory {
|
||||||
|
return &ClothingFactory{
|
||||||
|
clothingPool: make(map[string]ClothingInterface),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ClothingFactory) GetClothing(style, size, color string) ClothingInterface {
|
||||||
|
key := style + "-" + size + "-" + color
|
||||||
|
if clothing, exists := f.clothingPool[key]; exists {
|
||||||
|
return clothing
|
||||||
|
}
|
||||||
|
newClothing := &Clothing{style: style, size: size, color: color}
|
||||||
|
f.clothingPool[key] = newClothing
|
||||||
|
return newClothing
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ClothingFactory) ShowStock() {
|
||||||
|
fmt.Println("\n服装库存:")
|
||||||
|
for key, clothing := range f.clothingPool {
|
||||||
|
fmt.Printf("Key: %s -> ", key)
|
||||||
|
clothing.Show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客人
|
||||||
|
type Customer struct {
|
||||||
|
name string
|
||||||
|
clothing []ClothingInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCustomer(name string) *Customer {
|
||||||
|
return &Customer{
|
||||||
|
name: name,
|
||||||
|
clothing: []ClothingInterface{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Customer) RentClothing(clothing ClothingInterface) {
|
||||||
|
fmt.Printf("%s 租了一件服装: ", c.name)
|
||||||
|
clothing.Show()
|
||||||
|
c.clothing = append(c.clothing, clothing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Customer) ShowClothing() {
|
||||||
|
fmt.Printf("\n客人%s租赁的服装有:\n", c.name)
|
||||||
|
for _, cloth := range c.clothing {
|
||||||
|
cloth.Show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 享元模式 =============")
|
||||||
|
|
||||||
|
factory := NewClothingFactory()
|
||||||
|
|
||||||
|
// 客人1租衣服
|
||||||
|
customer1 := NewCustomer("小红")
|
||||||
|
customer1.RentClothing(factory.GetClothing("连衣裙", "M", "红色"))
|
||||||
|
customer1.RentClothing(factory.GetClothing("牛仔裤", "L", "蓝色"))
|
||||||
|
|
||||||
|
// 客人2租衣服
|
||||||
|
customer2 := NewCustomer("小明")
|
||||||
|
customer2.RentClothing(factory.GetClothing("连衣裙", "M", "红色")) // 共享同一件连衣裙
|
||||||
|
customer2.RentClothing(factory.GetClothing("西裤", "S", "白色"))
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// 显示租赁情况
|
||||||
|
customer1.ShowClothing()
|
||||||
|
customer2.ShowClothing()
|
||||||
|
|
||||||
|
// 显示服装库存
|
||||||
|
factory.ShowStock()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 享元模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
定义一种运算符,减号是加法,加号是减法。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象表达式
|
||||||
|
type Expression interface {
|
||||||
|
interpret() int
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终结符表达式:数字
|
||||||
|
type NumberExpression struct {
|
||||||
|
token string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NumberExpression) interpret() int {
|
||||||
|
num, _ := strconv.Atoi(n.token)
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式:加法
|
||||||
|
type AddExpression struct {
|
||||||
|
left, right Expression
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddExpression) interpret() int {
|
||||||
|
return a.left.interpret() - a.right.interpret()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式:减法
|
||||||
|
type SubExpression struct {
|
||||||
|
left, right Expression
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SubExpression) interpret() int {
|
||||||
|
return s.left.interpret() + s.right.interpret()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式工厂方法类型
|
||||||
|
type expressionFactory func(prev Expression, next string) Expression
|
||||||
|
|
||||||
|
// 解析器
|
||||||
|
// 分割表达式字符串,每个字符串逐步解析成表达式对象,最终组合成一个完整的表达式树
|
||||||
|
type Parser struct {
|
||||||
|
exp []string
|
||||||
|
index int
|
||||||
|
prev Expression
|
||||||
|
factories map[string]expressionFactory
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewParser() *Parser {
|
||||||
|
p := &Parser{
|
||||||
|
factories: make(map[string]expressionFactory),
|
||||||
|
}
|
||||||
|
p.factories["+"] = func(prev Expression, next string) Expression {
|
||||||
|
return &AddExpression{left: prev, right: p.newNumberExpression(next)}
|
||||||
|
}
|
||||||
|
p.factories["-"] = func(prev Expression, next string) Expression {
|
||||||
|
return &SubExpression{left: prev, right: p.newNumberExpression(next)}
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) newNumberExpression(token string) Expression {
|
||||||
|
return &NumberExpression{token: token}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parse(exp string) Expression {
|
||||||
|
sep := regexp.MustCompile(`\s+`)
|
||||||
|
p.exp = sep.Split(strings.TrimSpace(exp), -1)
|
||||||
|
p.index = 0
|
||||||
|
p.prev = nil
|
||||||
|
for p.index < len(p.exp) {
|
||||||
|
token := p.exp[p.index]
|
||||||
|
if factory, ok := p.factories[token]; ok {
|
||||||
|
p.index++
|
||||||
|
if p.index >= len(p.exp) {
|
||||||
|
fmt.Println("Last token is an operator, Ignored.")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p.prev == nil {
|
||||||
|
fmt.Println("Expression cannot start with an operator, Initialized with 0.")
|
||||||
|
p.prev = p.newNumberExpression("0")
|
||||||
|
}
|
||||||
|
token = p.exp[p.index]
|
||||||
|
p.prev = factory(p.prev, token)
|
||||||
|
} else {
|
||||||
|
p.prev = p.newNumberExpression(token)
|
||||||
|
}
|
||||||
|
p.index++
|
||||||
|
}
|
||||||
|
if p.prev == nil {
|
||||||
|
fmt.Println("No valid expression parsed.")
|
||||||
|
return p.newNumberExpression("0")
|
||||||
|
}
|
||||||
|
return p.prev
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("========== 解释器模式 ==========")
|
||||||
|
var raw string
|
||||||
|
parser := NewParser()
|
||||||
|
raw = "10 - 5"
|
||||||
|
fmt.Println(raw, "= ?")
|
||||||
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
||||||
|
|
||||||
|
fmt.Println("-----")
|
||||||
|
raw = "10 + 5"
|
||||||
|
fmt.Println(raw, "= ?")
|
||||||
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
||||||
|
|
||||||
|
fmt.Println("-----")
|
||||||
|
raw = "20 - 4 + 2 - 1"
|
||||||
|
fmt.Println(raw, "= ?")
|
||||||
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
||||||
|
|
||||||
|
fmt.Println("-----")
|
||||||
|
raw = " - 4 + 2 - "
|
||||||
|
fmt.Println(raw, "= ?")
|
||||||
|
fmt.Println(raw, "=", parser.parse(raw).interpret())
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("======== 解释器模式结束 ========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝有一张TODO表,记录着自己想干的事情。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 任务结构体 - 迭代器元素
|
||||||
|
type Todo struct {
|
||||||
|
content string
|
||||||
|
done bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// 迭代器接口
|
||||||
|
type Iterator interface {
|
||||||
|
First() *Todo
|
||||||
|
Next() *Todo
|
||||||
|
isDone() bool
|
||||||
|
CurrentItem() int
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体迭代器 - 汤宝宝的TODO表迭代器
|
||||||
|
type TodoListIterator struct {
|
||||||
|
todoList *TodoList
|
||||||
|
current int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TodoListIterator) First() *Todo {
|
||||||
|
t.current = 0
|
||||||
|
if len(t.todoList.todos) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return t.todoList.todos[t.current]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TodoListIterator) Next() *Todo {
|
||||||
|
t.current++
|
||||||
|
if t.isDone() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return t.todoList.todos[t.current]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TodoListIterator) isDone() bool {
|
||||||
|
return t.current >= len(t.todoList.todos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TodoListIterator) CurrentItem() int {
|
||||||
|
if t.isDone() {
|
||||||
|
return len(t.todoList.todos)
|
||||||
|
}
|
||||||
|
return t.current + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 集合接口
|
||||||
|
type Collection interface {
|
||||||
|
CreateIterator() Iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体集合 - 汤宝宝的TODO表
|
||||||
|
type TodoList struct {
|
||||||
|
todos []*Todo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TodoList) CreateIterator() Iterator {
|
||||||
|
return &TodoListIterator{
|
||||||
|
todoList: t,
|
||||||
|
current: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
fmt.Println("============= 迭代器模式 =============")
|
||||||
|
|
||||||
|
// 创建TODO表并添加任务
|
||||||
|
todoList := &TodoList{
|
||||||
|
todos: []*Todo{
|
||||||
|
{content: "学习Go语言", done: true},
|
||||||
|
{content: "完成设计模式作业", done: false},
|
||||||
|
{content: "锻炼身体", done: false},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建迭代器
|
||||||
|
iterator := todoList.CreateIterator()
|
||||||
|
|
||||||
|
// 使用迭代器遍历TODO表
|
||||||
|
for item := iterator.First(); !iterator.isDone(); item = iterator.Next() {
|
||||||
|
done := "已完成"
|
||||||
|
if !item.done {
|
||||||
|
done = "未完成"
|
||||||
|
}
|
||||||
|
fmt.Println("当前第", iterator.CurrentItem(), "项任务内容:", item.content, "是否完成:", done)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 迭代器模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
他负责把房东和租客撮合在一起,帮他们达成租房协议。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象中介者
|
||||||
|
type Mediator interface {
|
||||||
|
register(colleague Colleague)
|
||||||
|
Notify(sender Colleague, event string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体中介者 - 房产中介
|
||||||
|
type HousingMediator struct {
|
||||||
|
colleagues []Colleague
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *HousingMediator) register(colleague Colleague) {
|
||||||
|
if slices.Contains(m.colleagues, colleague) {
|
||||||
|
return // 已注册
|
||||||
|
}
|
||||||
|
m.colleagues = append(m.colleagues, colleague)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *HousingMediator) Notify(sender Colleague, event string) {
|
||||||
|
for _, colleague := range m.colleagues {
|
||||||
|
if colleague != sender {
|
||||||
|
colleague.Receive(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象同事类
|
||||||
|
type Colleague interface {
|
||||||
|
Send(event string)
|
||||||
|
Receive(event string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体同事类 - 房东
|
||||||
|
type Landlord struct {
|
||||||
|
mediator Mediator
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Landlord) Send(event string) {
|
||||||
|
fmt.Printf("房东%s发布信息: %s\n", l.name, event)
|
||||||
|
l.mediator.Notify(l, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Landlord) Receive(event string) {
|
||||||
|
fmt.Printf("房东%s收到通知: %s\n", l.name, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体同事类 - 租客
|
||||||
|
type Tenant struct {
|
||||||
|
mediator Mediator
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tenant) Send(event string) {
|
||||||
|
fmt.Printf("租客%s发布需求: %s\n", t.name, event)
|
||||||
|
t.mediator.Notify(t, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tenant) Receive(event string) {
|
||||||
|
fmt.Printf("租客%s收到通知: %s\n", t.name, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 中介者模式 =============")
|
||||||
|
|
||||||
|
mediator := &HousingMediator{}
|
||||||
|
|
||||||
|
landlord1 := &Landlord{mediator: mediator, name: "张三"}
|
||||||
|
landlord2 := &Landlord{mediator: mediator, name: "李四"}
|
||||||
|
tenant1 := &Tenant{mediator: mediator, name: "王五"}
|
||||||
|
tenant2 := &Tenant{mediator: mediator, name: "赵六"}
|
||||||
|
|
||||||
|
mediator.register(landlord1)
|
||||||
|
mediator.register(landlord2)
|
||||||
|
mediator.register(tenant1)
|
||||||
|
mediator.register(tenant2)
|
||||||
|
|
||||||
|
landlord1.Send("张三有一套两室一厅的房子出租,月租2000元。")
|
||||||
|
fmt.Println("-----")
|
||||||
|
tenant1.Send("王五需要一套三室的房子,预算3000元/月。")
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 中介者模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝聘请了一位私人助理,帮助他管理日常事务。
|
||||||
|
他负责记录汤宝宝的状态,以便在需要时恢复到之前的状态。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 原发器 - 汤宝宝
|
||||||
|
type Tom struct {
|
||||||
|
state string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tom) CreateMemento() *Memento {
|
||||||
|
m := &Memento{}
|
||||||
|
m.setState(t.state)
|
||||||
|
fmt.Println("汤宝宝创建了备忘录,状态为:", t.state)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tom) RestoreMemento(memento *Memento) {
|
||||||
|
t.state = memento.GetState()
|
||||||
|
fmt.Println("汤宝宝恢复了状态:", t.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备忘录
|
||||||
|
type Memento struct {
|
||||||
|
state string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memento) GetState() string {
|
||||||
|
return m.state
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Memento) setState(state string) {
|
||||||
|
m.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
// 负责人 - 私人助理
|
||||||
|
type Assistant struct {
|
||||||
|
mementos []*Memento
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Assistant) Backup(tom *Tom) {
|
||||||
|
a.mementos = append(a.mementos, tom.CreateMemento())
|
||||||
|
fmt.Println("私人助理备份了汤宝宝的状态")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Assistant) Undo(tom *Tom) {
|
||||||
|
if len(a.mementos) == 0 {
|
||||||
|
fmt.Println("没有备份可供恢复")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
memento := a.mementos[len(a.mementos)-1]
|
||||||
|
a.mementos = a.mementos[:len(a.mementos)-1]
|
||||||
|
fmt.Println("私人助理恢复了汤宝宝的状态")
|
||||||
|
tom.RestoreMemento(memento)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 备忘录模式 =============")
|
||||||
|
|
||||||
|
tom := &Tom{state: "开心"}
|
||||||
|
fmt.Println("汤宝宝的当前状态:", tom.state)
|
||||||
|
assistant := &Assistant{}
|
||||||
|
|
||||||
|
assistant.Backup(tom)
|
||||||
|
|
||||||
|
tom.state = "生气"
|
||||||
|
fmt.Println("汤宝宝的当前状态:", tom.state)
|
||||||
|
|
||||||
|
assistant.Undo(tom)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 备忘录模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
一旦片区内有房东发布了新房源信息,他就会第一时间通知所有潜在租客。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 观察者抽象接口
|
||||||
|
type Observer interface {
|
||||||
|
Update()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 目标抽象接口
|
||||||
|
type Subject interface {
|
||||||
|
Attach(observer Observer)
|
||||||
|
Detach(observer Observer)
|
||||||
|
Notify()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体目标 - 房产中介
|
||||||
|
type HousingAgency struct {
|
||||||
|
observers []Observer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HousingAgency) Attach(observer Observer) {
|
||||||
|
h.observers = append(h.observers, observer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HousingAgency) Detach(observer Observer) {
|
||||||
|
for i, obs := range h.observers {
|
||||||
|
if obs == observer {
|
||||||
|
h.observers = append(h.observers[:i], h.observers[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HousingAgency) Notify() {
|
||||||
|
fmt.Println("房产中介通知了所有租客。")
|
||||||
|
for _, observer := range h.observers {
|
||||||
|
observer.Update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体观察者 - 租客
|
||||||
|
type Tenant struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tenant) Update() {
|
||||||
|
fmt.Printf("租客%s收到了房源更新通知。\n", t.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 观察者模式 =============")
|
||||||
|
|
||||||
|
agency := &HousingAgency{}
|
||||||
|
|
||||||
|
tenant1 := &Tenant{name: "小明"}
|
||||||
|
tenant2 := &Tenant{name: "小红"}
|
||||||
|
|
||||||
|
fmt.Println("小红和小明订阅了房产中介的房源信息。")
|
||||||
|
agency.Attach(tenant1)
|
||||||
|
agency.Attach(tenant2)
|
||||||
|
fmt.Println("房源上新了!")
|
||||||
|
agency.Notify()
|
||||||
|
|
||||||
|
fmt.Println("-----")
|
||||||
|
fmt.Println("小红不想再接收房源信息,退订了。")
|
||||||
|
agency.Detach(tenant2)
|
||||||
|
fmt.Println("又有新房源了!")
|
||||||
|
agency.Notify()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 观察者模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝买火车票,可以去火车站买,也可以去代售点买,但是汤宝宝选择全都要。然而,火车站总共只剩两张票,这可苦了小明了。
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Seller interface {
|
||||||
|
Sell(name string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type TrainStation struct {
|
||||||
|
stock int
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTrainStation(stock int) *TrainStation {
|
||||||
|
fmt.Printf("火车站库存%d张票\n", stock)
|
||||||
|
return &TrainStation{stock: stock}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TrainStation) Sell(name string) error {
|
||||||
|
fmt.Printf("%s去火车站买票。\n", name)
|
||||||
|
if ts.stock > 0 {
|
||||||
|
ts.stock--
|
||||||
|
fmt.Printf("%s在火车站买到一张火车票。\n", name)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
fmt.Printf("火车站没有票了, %s没买到票。\n", name)
|
||||||
|
return fmt.Errorf("no ticket")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TicketAgency struct {
|
||||||
|
name string
|
||||||
|
station *TrainStation
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTicketAgency(name string, station *TrainStation) *TicketAgency {
|
||||||
|
return &TicketAgency{name: name, station: station}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tp *TicketAgency) Sell(name string) error {
|
||||||
|
fmt.Printf("%s去%s买票。\n", name, tp.name)
|
||||||
|
err := tp.station.Sell(tp.name)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s在%s没买到票。\n", name, tp.name)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("%s在%s买到一张火车票。\n", name, tp.name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 代理模式 =============")
|
||||||
|
station := newTrainStation(2)
|
||||||
|
agency := newTicketAgency("代售点A", station)
|
||||||
|
station.Sell("汤宝宝")
|
||||||
|
agency.Sell("汤宝宝")
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
agency.Sell("小明")
|
||||||
|
station.Sell("小明")
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 代理模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
一个任务状态机
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Task struct {
|
||||||
|
state State
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Task) SetState(state State) {
|
||||||
|
t.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Task) Handle() {
|
||||||
|
t.state.Handle(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态接口
|
||||||
|
type State interface {
|
||||||
|
Handle(t *Task)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 待处理
|
||||||
|
type PendingState struct{}
|
||||||
|
|
||||||
|
func (p *PendingState) Handle(t *Task) {
|
||||||
|
fmt.Println("任务待处理,开始处理任务...")
|
||||||
|
t.SetState(&InProgressState{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 进行中
|
||||||
|
type InProgressState struct{}
|
||||||
|
|
||||||
|
func (i *InProgressState) Handle(t *Task) {
|
||||||
|
fmt.Println("任务处理中,完成任务...")
|
||||||
|
t.SetState(&CompletedState{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 已完成
|
||||||
|
type CompletedState struct{}
|
||||||
|
|
||||||
|
func (c *CompletedState) Handle(t *Task) {
|
||||||
|
fmt.Println("任务已完成,无法再处理。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("============= 状态模式 =============")
|
||||||
|
|
||||||
|
task := &Task{state: &PendingState{}}
|
||||||
|
|
||||||
|
task.Handle()
|
||||||
|
task.Handle()
|
||||||
|
task.Handle()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("=========== 状态模式结束 ===========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝成为了收银员,消费者可以使用现金或者支付宝支付。
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Strategy interface {
|
||||||
|
Pay(amount float64) string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CashPayment struct{}
|
||||||
|
|
||||||
|
func (c *CashPayment) Pay(amount float64) string {
|
||||||
|
return fmt.Sprintf("使用现金支付了 %.2f 元", amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlipayPayment struct{}
|
||||||
|
|
||||||
|
func (a *AlipayPayment) Pay(amount float64) string {
|
||||||
|
return fmt.Sprintf("使用支付宝支付了 %.2f 元", amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
strategy Strategy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetStrategy(strategy Strategy) {
|
||||||
|
c.strategy = strategy
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Pay(amount float64) string {
|
||||||
|
return c.strategy.Pay(amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("=========== 策略模式 ===========")
|
||||||
|
|
||||||
|
context := &Context{}
|
||||||
|
|
||||||
|
context.SetStrategy(&CashPayment{})
|
||||||
|
fmt.Println(context.Pay(100))
|
||||||
|
|
||||||
|
context.SetStrategy(&AlipayPayment{})
|
||||||
|
fmt.Println(context.Pay(200))
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("========= 策略模式结束 =========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝炒西红柿鸡蛋。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象接口
|
||||||
|
type Dish interface {
|
||||||
|
PrepareIngredients()
|
||||||
|
Cook()
|
||||||
|
Serve()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模板方法
|
||||||
|
func DoCooking(dish Dish) {
|
||||||
|
fmt.Print("第一步:")
|
||||||
|
dish.PrepareIngredients()
|
||||||
|
fmt.Print("第二步:")
|
||||||
|
dish.Cook()
|
||||||
|
fmt.Print("第三步:")
|
||||||
|
dish.Serve()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体实现
|
||||||
|
type TomatoEggDish struct{}
|
||||||
|
|
||||||
|
func (t *TomatoEggDish) PrepareIngredients() {
|
||||||
|
fmt.Println("准备西红柿和鸡蛋;")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TomatoEggDish) Cook() {
|
||||||
|
fmt.Println("炒西红柿和鸡蛋;")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TomatoEggDish) Serve() {
|
||||||
|
fmt.Println("装盘,西红柿鸡蛋炒好了。")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("========== 模板方法模式 ==========")
|
||||||
|
dish := &TomatoEggDish{}
|
||||||
|
DoCooking(dish)
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("======== 模板方法模式结束 ========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝坚信搭积木是人类的未来,因此开办了一家积木厂。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象Node接口 Shape
|
||||||
|
type Shape interface {
|
||||||
|
Accept(visitor Visitor)
|
||||||
|
ClaimShape()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Circle struct{}
|
||||||
|
|
||||||
|
func (c *Circle) Accept(visitor Visitor) {
|
||||||
|
visitor.VisitCircle(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Circle) ClaimShape() {
|
||||||
|
fmt.Println("I am a Circle")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Square struct{}
|
||||||
|
|
||||||
|
func (s *Square) Accept(visitor Visitor) {
|
||||||
|
visitor.VisitSquare(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Square) ClaimShape() {
|
||||||
|
fmt.Println("I am a Square")
|
||||||
|
}
|
||||||
|
|
||||||
|
type Triangle struct{}
|
||||||
|
|
||||||
|
func (t *Triangle) Accept(visitor Visitor) {
|
||||||
|
visitor.VisitTriangle(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Triangle) ClaimShape() {
|
||||||
|
fmt.Println("I am a Triangle")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象NodeVisitor接口 Visitor
|
||||||
|
type Visitor interface {
|
||||||
|
VisitCircle(c *Circle)
|
||||||
|
VisitSquare(s *Square)
|
||||||
|
VisitTriangle(t *Triangle)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShapeVisitor struct{}
|
||||||
|
|
||||||
|
func (sv *ShapeVisitor) VisitCircle(c *Circle) {
|
||||||
|
fmt.Print("Visiting Circle: ")
|
||||||
|
c.ClaimShape()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sv *ShapeVisitor) VisitSquare(s *Square) {
|
||||||
|
fmt.Print("Visiting Square: ")
|
||||||
|
s.ClaimShape()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sv *ShapeVisitor) VisitTriangle(t *Triangle) {
|
||||||
|
fmt.Print("Visiting Triangle: ")
|
||||||
|
t.ClaimShape()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("========== 访问者模式 ==========")
|
||||||
|
shapes := []Shape{&Circle{}, &Square{}, &Triangle{}}
|
||||||
|
visitor := &ShapeVisitor{}
|
||||||
|
|
||||||
|
for _, shape := range shapes {
|
||||||
|
shape.Accept(visitor)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("======== 访问者模式结束 ========")
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝申请报销款,需要走产品经理、部门经理和总经理的审核~
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Manager:
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
self.successor = None
|
||||||
|
self.amount = 0
|
||||||
|
|
||||||
|
def set_successor(self, manager: 'Manager'):
|
||||||
|
self.successor = manager
|
||||||
|
print(f"{self.name}的下一级经理是{manager.name}")
|
||||||
|
|
||||||
|
def set_amount_right(self, amount: float):
|
||||||
|
self.amount = amount
|
||||||
|
print(f"{self.name}的报销权限是{amount:.2f}元")
|
||||||
|
|
||||||
|
def have_right(self, amount: float) -> bool:
|
||||||
|
right = amount <= self.amount
|
||||||
|
if right:
|
||||||
|
print(f"{self.name}有权限审批{amount:.2f}元的报销请求")
|
||||||
|
else:
|
||||||
|
print(f"{self.name}没有权限审批{amount:.2f}元的报销请求")
|
||||||
|
return right
|
||||||
|
|
||||||
|
def approve(self, name:str, amount: float):
|
||||||
|
print(f"{name}提交了一笔{amount:.2f}元的报销请求")
|
||||||
|
if self.have_right(amount):
|
||||||
|
print(f"{self.name}审批通过了{name}的报销请求,金额为{amount:.2f}元")
|
||||||
|
elif self.successor:
|
||||||
|
print(f"{self.name}将{name}的报销请求上报给{self.successor.name}审批")
|
||||||
|
self.successor.approve(name, amount)
|
||||||
|
else:
|
||||||
|
print(f"没有合适的经理审批{name}的报销请求,金额为{amount:.2f}元")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("========= 责任链模式 =========")
|
||||||
|
|
||||||
|
# 创建经理
|
||||||
|
pm = Manager("产品经理")
|
||||||
|
pm.set_amount_right(1000)
|
||||||
|
dm = Manager("部门经理")
|
||||||
|
dm.set_amount_right(5000)
|
||||||
|
gm = Manager("总经理")
|
||||||
|
gm.set_amount_right(20000)
|
||||||
|
|
||||||
|
# 设置责任链
|
||||||
|
pm.set_successor(dm)
|
||||||
|
dm.set_successor(gm)
|
||||||
|
|
||||||
|
# 提交报销请求
|
||||||
|
print("-----")
|
||||||
|
pm.approve("汤宝宝", 800)
|
||||||
|
print("-----")
|
||||||
|
pm.approve("汤宝宝", 3000)
|
||||||
|
print("-----")
|
||||||
|
pm.approve("汤宝宝", 15000)
|
||||||
|
print("-----")
|
||||||
|
pm.approve("汤宝宝", 25000)
|
||||||
|
|
||||||
|
print("\n======= 责任链模式结束 =======")
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝成为一国之王,手下有一个传令官和三个大臣,分别是内政大臣、外交大臣和军事大臣。
|
||||||
|
有一天,汤宝宝想要发布一个命令,传令官负责将命令传达给大臣们,大臣们根据命令的内容决定是否执行。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# 接收者接口
|
||||||
|
class Receiver(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def perform(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 内政大臣
|
||||||
|
class HomeSecretary(Receiver):
|
||||||
|
is_performing: bool
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.is_performing = False
|
||||||
|
|
||||||
|
def perform(self):
|
||||||
|
self.is_performing = True
|
||||||
|
print("内政大臣开始执行命令")
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
self.is_performing = False
|
||||||
|
print("内政大臣取消执行命令")
|
||||||
|
|
||||||
|
|
||||||
|
# 外交大臣
|
||||||
|
class ForeignSecretary(Receiver):
|
||||||
|
is_performing: bool
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.is_performing = False
|
||||||
|
|
||||||
|
def perform(self):
|
||||||
|
self.is_performing = True
|
||||||
|
print("外交大臣开始执行命令")
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
self.is_performing = False
|
||||||
|
print("外交大臣取消执行命令")
|
||||||
|
|
||||||
|
|
||||||
|
# 军事大臣
|
||||||
|
class DefenseSecretary(Receiver):
|
||||||
|
is_performing: bool
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.is_performing = False
|
||||||
|
|
||||||
|
def perform(self):
|
||||||
|
self.is_performing = True
|
||||||
|
print("军事大臣开始执行命令")
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
self.is_performing = False
|
||||||
|
print("军事大臣取消执行命令")
|
||||||
|
|
||||||
|
|
||||||
|
# 命令接口
|
||||||
|
class Command(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def execute(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 执行命令
|
||||||
|
class performCommand(Command):
|
||||||
|
receiver: Receiver
|
||||||
|
|
||||||
|
def __init__(self, receiver: Receiver):
|
||||||
|
self.receiver = receiver
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
self.receiver.perform()
|
||||||
|
|
||||||
|
|
||||||
|
# 取消命令
|
||||||
|
class abortCommand(Command):
|
||||||
|
receiver: Receiver
|
||||||
|
|
||||||
|
def __init__(self, receiver: Receiver):
|
||||||
|
self.receiver = receiver
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
self.receiver.abort()
|
||||||
|
|
||||||
|
|
||||||
|
# 传令官
|
||||||
|
class Herald:
|
||||||
|
commands: list[Command]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.commands = []
|
||||||
|
|
||||||
|
def addCommand(self, command: Command):
|
||||||
|
self.commands.append(command)
|
||||||
|
|
||||||
|
def executeCommands(self):
|
||||||
|
for command in self.commands:
|
||||||
|
command.execute()
|
||||||
|
self.commands.clear()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("========= 命令模式 =========")
|
||||||
|
# 创建接收者
|
||||||
|
home_secretary = HomeSecretary()
|
||||||
|
foreign_secretary = ForeignSecretary()
|
||||||
|
defense_secretary = DefenseSecretary()
|
||||||
|
|
||||||
|
# 创建命令
|
||||||
|
perform_home_command = performCommand(home_secretary)
|
||||||
|
perform_foreign_command = performCommand(foreign_secretary)
|
||||||
|
perform_defense_command = performCommand(defense_secretary)
|
||||||
|
|
||||||
|
abort_home_command = abortCommand(home_secretary)
|
||||||
|
abort_foreign_command = abortCommand(foreign_secretary)
|
||||||
|
abort_defense_command = abortCommand(defense_secretary)
|
||||||
|
|
||||||
|
# 创建传令官
|
||||||
|
herald = Herald()
|
||||||
|
|
||||||
|
# 添加执行命令
|
||||||
|
herald.addCommand(perform_home_command)
|
||||||
|
herald.addCommand(perform_foreign_command)
|
||||||
|
herald.addCommand(perform_defense_command)
|
||||||
|
|
||||||
|
# 执行命令
|
||||||
|
herald.executeCommands()
|
||||||
|
|
||||||
|
# 添加取消命令
|
||||||
|
herald.addCommand(abort_home_command)
|
||||||
|
herald.addCommand(abort_foreign_command)
|
||||||
|
herald.addCommand(abort_defense_command)
|
||||||
|
|
||||||
|
# 执行取消命令
|
||||||
|
herald.executeCommands()
|
||||||
|
|
||||||
|
print("\n======= 命令模式结束 =======")
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
"""
|
||||||
|
实例
|
||||||
|
汤宝宝教你番茄炒蛋~
|
||||||
|
"""
|
||||||
|
|
||||||
|
class TomatoEgg:
|
||||||
|
def serve(self):
|
||||||
|
print("番茄炒蛋上桌啦!")
|
||||||
|
|
||||||
|
class CutTomato:
|
||||||
|
def cut(self):
|
||||||
|
print("番茄切好了!")
|
||||||
|
|
||||||
|
class BeatEgg:
|
||||||
|
def beat(self):
|
||||||
|
print("鸡蛋打好了!")
|
||||||
|
|
||||||
|
class Cook:
|
||||||
|
cutTomato: CutTomato
|
||||||
|
beatEgg: BeatEgg
|
||||||
|
|
||||||
|
def __init__(self,cutTomato: CutTomato, beatEgg: BeatEgg) -> None:
|
||||||
|
self.cutTomato = cutTomato
|
||||||
|
self.beatEgg = beatEgg
|
||||||
|
|
||||||
|
def cook_dish(self):
|
||||||
|
self.cutTomato.cut()
|
||||||
|
self.beatEgg.beat()
|
||||||
|
print("食材放入锅中,开火加热。")
|
||||||
|
print("番茄炒蛋炒好了。")
|
||||||
|
|
||||||
|
# 外观
|
||||||
|
class ChefFacade:
|
||||||
|
cook: Cook
|
||||||
|
dish: TomatoEgg
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.cook = Cook(CutTomato(), BeatEgg())
|
||||||
|
self.dish = TomatoEgg()
|
||||||
|
|
||||||
|
def prepare_and_serve(self):
|
||||||
|
print("准备食材...")
|
||||||
|
self.cook.cook_dish()
|
||||||
|
self.dish.serve()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 外观模式 =============")
|
||||||
|
chef = ChefFacade()
|
||||||
|
chef.prepare_and_serve()
|
||||||
|
print("\n=========== 外观模式结束 ===========")
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝开了一家服装租赁店,好多客人来店里租衣服~
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
# 享元接口
|
||||||
|
class ClothingInterface(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def show(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Clothing(ClothingInterface):
|
||||||
|
"""享元对象 - 服装"""
|
||||||
|
|
||||||
|
style: str
|
||||||
|
size: str
|
||||||
|
color: str
|
||||||
|
|
||||||
|
def __init__(self, style: str, size: str, color: str):
|
||||||
|
self.style = style
|
||||||
|
self.size = size
|
||||||
|
self.color = color
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
print(f"服装款式: {self.style}, 尺码: {self.size}, 颜色: {self.color}")
|
||||||
|
|
||||||
|
|
||||||
|
class ClothingFactory:
|
||||||
|
"""享元工厂 - 服装店"""
|
||||||
|
|
||||||
|
_clothing_pool: dict[str, ClothingInterface]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._clothing_pool = {}
|
||||||
|
|
||||||
|
def get_clothing(self, style: str, size: str, color: str) -> ClothingInterface:
|
||||||
|
key = f"{style}-{size}-{color}"
|
||||||
|
if key not in self._clothing_pool:
|
||||||
|
self._clothing_pool[key] = Clothing(style, size, color)
|
||||||
|
return self._clothing_pool[key]
|
||||||
|
|
||||||
|
def show_stock(self):
|
||||||
|
print("\n服装库存:")
|
||||||
|
for key, clothing in self._clothing_pool.items():
|
||||||
|
print(f"Keys: {key} -> ", end="")
|
||||||
|
clothing.show()
|
||||||
|
|
||||||
|
|
||||||
|
class Customer:
|
||||||
|
name: str
|
||||||
|
clothing: list[ClothingInterface]
|
||||||
|
|
||||||
|
def __init__(self, name: str):
|
||||||
|
self.name = name
|
||||||
|
self.clothing = []
|
||||||
|
|
||||||
|
def rent_clothing(self, clothing: ClothingInterface):
|
||||||
|
self.clothing.append(clothing)
|
||||||
|
print(f"{self.name} 租了一件服装: ", end="")
|
||||||
|
clothing.show()
|
||||||
|
|
||||||
|
def show_clothing(self):
|
||||||
|
print(f"\n客人{self.name} 租赁的服装有:")
|
||||||
|
for clothing in self.clothing:
|
||||||
|
clothing.show()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 享元模式 =============")
|
||||||
|
factory = ClothingFactory()
|
||||||
|
# 客人1租衣服
|
||||||
|
customer1 = Customer("小红")
|
||||||
|
customer1.rent_clothing(factory.get_clothing("连衣裙", "M", "红色"))
|
||||||
|
customer1.rent_clothing(factory.get_clothing("牛仔裤", "L", "蓝色"))
|
||||||
|
# 客人2租衣服
|
||||||
|
customer2 = Customer("小明")
|
||||||
|
customer2.rent_clothing(factory.get_clothing("连衣裙", "M", "红色"))
|
||||||
|
customer2.rent_clothing(factory.get_clothing("西裤", "S", "白色"))
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 显示租赁情况
|
||||||
|
customer1.show_clothing()
|
||||||
|
customer2.show_clothing()
|
||||||
|
|
||||||
|
# 显示服装库存
|
||||||
|
factory.show_stock()
|
||||||
|
|
||||||
|
print("\n=========== 享元模式结束 ===========")
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
定义一种运算符,减号是加法,加号是减法。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
# 抽象表达式
|
||||||
|
class Expression(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def interpret(self) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 终结符表达式:数字
|
||||||
|
class NumberExpression(Expression):
|
||||||
|
def __init__(self, token: str):
|
||||||
|
self.token = token
|
||||||
|
|
||||||
|
def interpret(self) -> int:
|
||||||
|
return int(self.token)
|
||||||
|
|
||||||
|
|
||||||
|
# 非终结符表达式:加法
|
||||||
|
class AddExpression(Expression):
|
||||||
|
def __init__(self, left: Expression, right: Expression):
|
||||||
|
self.left = left
|
||||||
|
self.right = right
|
||||||
|
|
||||||
|
def interpret(self) -> int:
|
||||||
|
return self.left.interpret() - self.right.interpret()
|
||||||
|
|
||||||
|
|
||||||
|
# 非终结符表达式:减法
|
||||||
|
class SubExpression(Expression):
|
||||||
|
def __init__(self, left: Expression, right: Expression):
|
||||||
|
self.left = left
|
||||||
|
self.right = right
|
||||||
|
|
||||||
|
def interpret(self) -> int:
|
||||||
|
return self.left.interpret() + self.right.interpret()
|
||||||
|
|
||||||
|
# 解析器
|
||||||
|
class Parser:
|
||||||
|
exp: list[str]
|
||||||
|
index: int
|
||||||
|
prev: Expression | None
|
||||||
|
factories: dict[str, Callable[[Expression, str], Expression]]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.factories = {}
|
||||||
|
self.factories["+"] = lambda prev, next: AddExpression(prev, self.newNumberExpression(next))
|
||||||
|
self.factories["-"] = lambda prev, next: SubExpression(prev, self.newNumberExpression(next))
|
||||||
|
|
||||||
|
def newNumberExpression(self, token: str) -> Expression:
|
||||||
|
return NumberExpression(token)
|
||||||
|
|
||||||
|
def parse(self, exp: str) -> Expression:
|
||||||
|
self.exp = exp.split()
|
||||||
|
self.index = 0
|
||||||
|
self.prev = None
|
||||||
|
while self.index < len(self.exp):
|
||||||
|
token = self.exp[self.index]
|
||||||
|
if token in self.factories:
|
||||||
|
factory = self.factories[token]
|
||||||
|
self.index += 1
|
||||||
|
if self.index >= len(self.exp):
|
||||||
|
print("Last token is an operator, Ignored.")
|
||||||
|
break
|
||||||
|
token = self.exp[self.index]
|
||||||
|
if self.prev is None:
|
||||||
|
print("Expression cannot start with an operator, Initialized with 0.")
|
||||||
|
self.prev = self.newNumberExpression("0")
|
||||||
|
self.prev = factory(self.prev, token)
|
||||||
|
else:
|
||||||
|
self.prev = self.newNumberExpression(token)
|
||||||
|
self.index += 1
|
||||||
|
if self.prev is None:
|
||||||
|
print("No valid expression parsed.")
|
||||||
|
return self.newNumberExpression("0")
|
||||||
|
return self.prev
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("========== 解释器模式 ==========")
|
||||||
|
parser = Parser()
|
||||||
|
|
||||||
|
raw = "10 - 5"
|
||||||
|
print(f"{raw} = ?")
|
||||||
|
print(f"{raw} = {parser.parse(raw).interpret()}")
|
||||||
|
|
||||||
|
print("-----")
|
||||||
|
raw = "10 + 5"
|
||||||
|
print(f"{raw} = ?")
|
||||||
|
print(f"{raw} = {parser.parse(raw).interpret()}")
|
||||||
|
|
||||||
|
print("-----")
|
||||||
|
raw = "20 - 4 + 2 - 1"
|
||||||
|
print(f"{raw} = ?")
|
||||||
|
print(f"{raw} = {parser.parse(raw).interpret()}")
|
||||||
|
|
||||||
|
print("-----")
|
||||||
|
raw = " - 4 + 2 - "
|
||||||
|
print(f"{raw} = ?")
|
||||||
|
print(f"{raw} = {parser.parse(raw).interpret()}")
|
||||||
|
|
||||||
|
print("\n======== 解释器模式结束 ========")
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝有一张TODO表,记录着自己想干的事情。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# 任务结构体 - 迭代器元素
|
||||||
|
class Todo:
|
||||||
|
content: str
|
||||||
|
done: bool
|
||||||
|
|
||||||
|
def __init__(self, content: str, done: bool = False):
|
||||||
|
self.content = content
|
||||||
|
self.done = done
|
||||||
|
|
||||||
|
|
||||||
|
# 集合接口
|
||||||
|
class Collection(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def CreateIterator(self) -> "Iterator":
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 具体集合 - 汤宝宝的TODO表
|
||||||
|
class TodoList(Collection):
|
||||||
|
todos: list[Todo]
|
||||||
|
|
||||||
|
def __init__(self, todos: list[Todo]):
|
||||||
|
self.todos = todos
|
||||||
|
|
||||||
|
def CreateIterator(self) -> "Iterator":
|
||||||
|
return TodoListIterator(self)
|
||||||
|
|
||||||
|
|
||||||
|
# 迭代器接口
|
||||||
|
class Iterator(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def First(self) -> Todo:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def Next(self) -> Todo | None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def isDone(self) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def CurrentItem(self) -> int:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 具体迭代器 - 汤宝宝的TODO表迭代器
|
||||||
|
class TodoListIterator(Iterator):
|
||||||
|
def __init__(self, todo_list: "TodoList"):
|
||||||
|
self._todo_list = todo_list
|
||||||
|
self._current = 0
|
||||||
|
|
||||||
|
def First(self) -> Todo:
|
||||||
|
self._current = 0
|
||||||
|
return self._todo_list.todos[self._current]
|
||||||
|
|
||||||
|
def Next(self) -> Todo | None:
|
||||||
|
self._current += 1
|
||||||
|
if not self.isDone():
|
||||||
|
return self._todo_list.todos[self._current]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def isDone(self) -> bool:
|
||||||
|
return self._current >= len(self._todo_list.todos)
|
||||||
|
|
||||||
|
def CurrentItem(self) -> int:
|
||||||
|
if self.isDone():
|
||||||
|
return len(self._todo_list.todos)
|
||||||
|
return self._current + 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 迭代器模式 =============")
|
||||||
|
|
||||||
|
# 创建TODO表并添加任务
|
||||||
|
todo_list = TodoList(
|
||||||
|
todos=[
|
||||||
|
Todo("学习Go语言", True),
|
||||||
|
Todo("完成设计模式作业", False),
|
||||||
|
Todo("锻炼身体", False),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# 创建迭代器
|
||||||
|
iterator = todo_list.CreateIterator()
|
||||||
|
|
||||||
|
# 使用迭代器遍历TODO表
|
||||||
|
item = iterator.First()
|
||||||
|
while not iterator.isDone():
|
||||||
|
done = "已完成" if item and item.done else "未完成"
|
||||||
|
print(
|
||||||
|
f"当前第 {iterator.CurrentItem()} 项任务内容: {item.content if item else ''} 是否完成: {done}"
|
||||||
|
)
|
||||||
|
item = iterator.Next()
|
||||||
|
|
||||||
|
print("\n=========== 迭代器模式结束 ===========")
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
他负责把房东和租客撮合在一起,帮他们达成租房协议。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象同事类
|
||||||
|
class Colleague(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def send(self, event: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def receive(self, event: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象中介者
|
||||||
|
class Mediator(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def notify(self, sender: Colleague, event: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def register(self, colleague: Colleague) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 具体同事类:房东
|
||||||
|
class Landlord(Colleague):
|
||||||
|
mediator: Mediator
|
||||||
|
name: str
|
||||||
|
|
||||||
|
def __init__(self, mediator: Mediator, name: str) -> None:
|
||||||
|
self.mediator = mediator
|
||||||
|
self.name = name
|
||||||
|
self.mediator.register(self)
|
||||||
|
|
||||||
|
def send(self, event: str) -> None:
|
||||||
|
print(f"房东{self.name}发布信息: {event}")
|
||||||
|
self.mediator.notify(self, event)
|
||||||
|
|
||||||
|
def receive(self, event: str) -> None:
|
||||||
|
print(f"房东{self.name}收到通知: {event}")
|
||||||
|
|
||||||
|
|
||||||
|
# 具体同事类:租客
|
||||||
|
class Tenant(Colleague):
|
||||||
|
mediator: Mediator
|
||||||
|
name: str
|
||||||
|
|
||||||
|
def __init__(self, mediator: Mediator, name: str) -> None:
|
||||||
|
self.mediator = mediator
|
||||||
|
self.name = name
|
||||||
|
self.mediator.register(self)
|
||||||
|
|
||||||
|
def send(self, event: str) -> None:
|
||||||
|
print(f"租客{self.name}发布需求: {event}")
|
||||||
|
self.mediator.notify(self, event)
|
||||||
|
|
||||||
|
def receive(self, event: str) -> None:
|
||||||
|
print(f"租客{self.name}收到通知: {event}")
|
||||||
|
|
||||||
|
|
||||||
|
# 具体中介者类
|
||||||
|
class HousingMediator(Mediator):
|
||||||
|
colleagues: list[Colleague] = []
|
||||||
|
|
||||||
|
def register(self, colleague: Colleague) -> None:
|
||||||
|
if colleague not in self.colleagues:
|
||||||
|
self.colleagues.append(colleague)
|
||||||
|
|
||||||
|
def notify(self, sender: Colleague, event: str) -> None:
|
||||||
|
for colleague in self.colleagues:
|
||||||
|
if colleague != sender:
|
||||||
|
colleague.receive(event)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 中介者模式 =============")
|
||||||
|
|
||||||
|
mediator = HousingMediator()
|
||||||
|
|
||||||
|
landlord1 = Landlord(mediator, "张三")
|
||||||
|
landlord2 = Landlord(mediator, "李四")
|
||||||
|
tenant1 = Tenant(mediator, "王五")
|
||||||
|
tenant2 = Tenant(mediator, "赵六")
|
||||||
|
|
||||||
|
landlord1.send("张三有一套两室一厅的房子出租,月租2000元。")
|
||||||
|
print("-----")
|
||||||
|
tenant1.send("王五需要一套三室的房子,预算3000元/月。")
|
||||||
|
|
||||||
|
print("\n=========== 中介者模式结束 ===========")
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
"""实例:
|
||||||
|
汤宝宝聘请了一位私人助理,帮助他管理日常事务。
|
||||||
|
他负责记录汤宝宝的状态,以便在需要时恢复到之前的状态。
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Tom:
|
||||||
|
state: str
|
||||||
|
|
||||||
|
def __init__(self, state: str) -> None:
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
def create_memento(self):
|
||||||
|
m = Memento(self.state)
|
||||||
|
print(f"汤宝宝创建了备忘录,状态为:{m.get_state()}")
|
||||||
|
return m
|
||||||
|
|
||||||
|
def restore_memento(self, memento):
|
||||||
|
self.state = memento.get_state()
|
||||||
|
print(f"汤宝宝恢复了状态:{self.state}")
|
||||||
|
|
||||||
|
|
||||||
|
class Memento:
|
||||||
|
__state: str
|
||||||
|
|
||||||
|
def __init__(self, state: str) -> None:
|
||||||
|
self.__state = state
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return self.__state
|
||||||
|
|
||||||
|
def set_state(self, state: str):
|
||||||
|
self.__state = state
|
||||||
|
|
||||||
|
|
||||||
|
class Assistant:
|
||||||
|
__memento_list = []
|
||||||
|
|
||||||
|
def backup(self, tom: Tom):
|
||||||
|
self.__memento_list.append(tom.create_memento())
|
||||||
|
|
||||||
|
def undo(self, tom: Tom):
|
||||||
|
if not self.__memento_list:
|
||||||
|
print("没有备份可供恢复")
|
||||||
|
return
|
||||||
|
memento = self.__memento_list.pop()
|
||||||
|
print("私人助理恢复了汤宝宝的状态")
|
||||||
|
tom.restore_memento(memento)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 备忘录模式 =============")
|
||||||
|
|
||||||
|
tom = Tom("开心")
|
||||||
|
print(f"汤宝宝的当前状态:{tom.state}")
|
||||||
|
assistant = Assistant()
|
||||||
|
|
||||||
|
assistant.backup(tom)
|
||||||
|
tom.state = "生气"
|
||||||
|
print(f"汤宝宝的当前状态:{tom.state}")
|
||||||
|
|
||||||
|
assistant.undo(tom)
|
||||||
|
|
||||||
|
print("\n=========== 备忘录模式结束 ===========")
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
一旦片区内有房东发布了新房源信息,他就会第一时间通知所有潜在租客。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象观察者类
|
||||||
|
class Observer(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def update(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象目标接口
|
||||||
|
class Subject(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def attach(self, observer: Observer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def detach(self, observer: Observer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def notify(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 具体目标类
|
||||||
|
class HousingAgency(Subject):
|
||||||
|
def __init__(self):
|
||||||
|
self._observers = []
|
||||||
|
|
||||||
|
def attach(self, observer: Observer):
|
||||||
|
self._observers.append(observer)
|
||||||
|
|
||||||
|
def detach(self, observer: Observer):
|
||||||
|
self._observers.remove(observer)
|
||||||
|
|
||||||
|
def notify(self):
|
||||||
|
print("房产中介通知了所有租客。")
|
||||||
|
for observer in self._observers:
|
||||||
|
observer.update()
|
||||||
|
|
||||||
|
|
||||||
|
# 具体观察者类
|
||||||
|
class Tenant(Observer):
|
||||||
|
def __init__(self, name: str):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
print(f"租客{self.name}收到房源更新通知!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 观察者模式 =============")
|
||||||
|
|
||||||
|
agency = HousingAgency()
|
||||||
|
tenant1 = Tenant("小明")
|
||||||
|
tenant2 = Tenant("小红")
|
||||||
|
|
||||||
|
print("小红和小明订阅了房产中介的房源信息。")
|
||||||
|
agency.attach(tenant1)
|
||||||
|
agency.attach(tenant2)
|
||||||
|
|
||||||
|
print("房源上新了!")
|
||||||
|
agency.notify()
|
||||||
|
|
||||||
|
print("-----")
|
||||||
|
print("小红不想再接收房源信息,退订了。")
|
||||||
|
agency.detach(tenant2)
|
||||||
|
print("又有新房源了!")
|
||||||
|
agency.notify()
|
||||||
|
|
||||||
|
print("\n=========== 观察者模式结束 ===========")
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝买火车票,可以去火车站买,也可以去代售点买,但是汤宝宝选择全都要。然而,火车站总共只剩两张票,这可苦了小明了。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class Seller(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def sell(self, name: str) -> bool:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TrainStation(Seller):
|
||||||
|
stock: int
|
||||||
|
|
||||||
|
def __init__(self, stock: int) -> None:
|
||||||
|
print(f"火车站库存{stock}张票")
|
||||||
|
self.stock = stock
|
||||||
|
|
||||||
|
def sell(self, name: str) -> bool:
|
||||||
|
print(f"{name}去火车站买票。")
|
||||||
|
if self.stock > 0:
|
||||||
|
self.stock -= 1
|
||||||
|
print(f"{name}在火车站买到一张火车票。")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"火车站没票了,{name}没买到票。")
|
||||||
|
return False
|
||||||
|
|
||||||
|
class TicketAgency(Seller):
|
||||||
|
name: str
|
||||||
|
station: TrainStation
|
||||||
|
|
||||||
|
def __init__(self, name: str, station: TrainStation) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.station = station
|
||||||
|
|
||||||
|
def sell(self, name: str) -> bool:
|
||||||
|
print(f"{name}去{self.name}买票。")
|
||||||
|
result = self.station.sell(self.name)
|
||||||
|
if result:
|
||||||
|
print(f"{name}在{self.name}买到一张火车票。")
|
||||||
|
else:
|
||||||
|
print(f"{name}在{self.name}没买到票。")
|
||||||
|
return result
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 代理模式 =============")
|
||||||
|
station = TrainStation(stock=2)
|
||||||
|
agency = TicketAgency(name="代售点A", station=station)
|
||||||
|
station.sell("汤宝宝")
|
||||||
|
agency.sell("汤宝宝")
|
||||||
|
print("")
|
||||||
|
agency.sell("小明")
|
||||||
|
station.sell("小明")
|
||||||
|
|
||||||
|
print("\n=========== 代理模式结束 ===========")
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
一个任务状态机
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
class Task:
|
||||||
|
state: 'State'
|
||||||
|
def __init__(self):
|
||||||
|
self.set_state(PendingState())
|
||||||
|
|
||||||
|
def set_state(self, state: 'State'):
|
||||||
|
self.state = state
|
||||||
|
|
||||||
|
def handle(self):
|
||||||
|
self.state.handle(self)
|
||||||
|
|
||||||
|
|
||||||
|
# 状态接口
|
||||||
|
class State(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def handle(self, context):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 具体状态 - 待处理
|
||||||
|
class PendingState(State):
|
||||||
|
def handle(self, context):
|
||||||
|
print("任务待处理,开始处理任务...")
|
||||||
|
context.set_state(InProgressState())
|
||||||
|
|
||||||
|
# 具体状态 - 处理中
|
||||||
|
class InProgressState(State):
|
||||||
|
def handle(self, context):
|
||||||
|
print("任务处理中,完成任务...")
|
||||||
|
context.set_state(CompletedState())
|
||||||
|
|
||||||
|
# 具体状态 - 已完成
|
||||||
|
class CompletedState(State):
|
||||||
|
def handle(self, context):
|
||||||
|
print("任务已完成,无法再处理。")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("============= 状态模式 =============")
|
||||||
|
task = Task()
|
||||||
|
task.handle()
|
||||||
|
task.handle()
|
||||||
|
task.handle()
|
||||||
|
print("\n=========== 状态模式结束 ===========")
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝成为了收银员,消费者可以使用现金或者支付宝支付。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class Strategy(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def pay(self, amount: float) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CashPayment(Strategy):
|
||||||
|
def pay(self, amount: float) -> str:
|
||||||
|
return(f"使用现金支付了 {amount:.2f} 元。")
|
||||||
|
|
||||||
|
|
||||||
|
class AlipayPayment(Strategy):
|
||||||
|
def pay(self, amount: float) -> str:
|
||||||
|
return(f"使用支付宝支付了 {amount:.2f} 元。")
|
||||||
|
|
||||||
|
|
||||||
|
class Context:
|
||||||
|
strategy: Strategy
|
||||||
|
|
||||||
|
def set_strategy(self, strategy: Strategy) -> None:
|
||||||
|
self._strategy = strategy
|
||||||
|
|
||||||
|
def pay(self, amount: float) -> str:
|
||||||
|
return self._strategy.pay(amount)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=========== 策略模式 ===========")
|
||||||
|
|
||||||
|
context = Context()
|
||||||
|
context.set_strategy(CashPayment())
|
||||||
|
print(context.pay(100.0))
|
||||||
|
context.set_strategy(AlipayPayment())
|
||||||
|
print(context.pay(200.0))
|
||||||
|
|
||||||
|
print("\n========= 策略模式结束 =========")
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝炒西红柿鸡蛋。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class Dish(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def prepare_ingredients(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def cook(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def serve(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_cooking(self):
|
||||||
|
print("第一步:", end="")
|
||||||
|
self.prepare_ingredients()
|
||||||
|
print("第二步:", end="")
|
||||||
|
self.cook()
|
||||||
|
print("第三步:", end="")
|
||||||
|
self.serve()
|
||||||
|
|
||||||
|
class TomatoEggDish(Dish):
|
||||||
|
def prepare_ingredients(self):
|
||||||
|
print("准备西红柿和鸡蛋。")
|
||||||
|
|
||||||
|
def cook(self):
|
||||||
|
print("炒西红柿和鸡蛋。")
|
||||||
|
|
||||||
|
def serve(self):
|
||||||
|
print("装盘,西红柿鸡蛋炒好了。")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("========== 模板方法模式 ==========")
|
||||||
|
dish = TomatoEggDish()
|
||||||
|
dish.do_cooking()
|
||||||
|
print("\n======== 模板方法模式结束 ========")
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
"""
|
||||||
|
实例:
|
||||||
|
汤宝宝坚信搭积木是人类的未来,因此开办了一家积木厂。
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象Node接口 Shape
|
||||||
|
class Shape(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def accept(self, visitor: "Visitor"):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def claim_shape(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Circle(Shape):
|
||||||
|
def accept(self, visitor):
|
||||||
|
visitor.visit_circle(self)
|
||||||
|
|
||||||
|
def claim_shape(self):
|
||||||
|
print("I am a Circle")
|
||||||
|
|
||||||
|
|
||||||
|
class Square(Shape):
|
||||||
|
def accept(self, visitor):
|
||||||
|
visitor.visit_square(self)
|
||||||
|
|
||||||
|
def claim_shape(self):
|
||||||
|
print("I am a Square")
|
||||||
|
|
||||||
|
|
||||||
|
class Triangle(Shape):
|
||||||
|
def accept(self, visitor):
|
||||||
|
visitor.visit_triangle(self)
|
||||||
|
|
||||||
|
def claim_shape(self):
|
||||||
|
print("I am a Triangle")
|
||||||
|
|
||||||
|
|
||||||
|
# 抽象Visitor接口
|
||||||
|
class Visitor(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def visit_circle(self, circle: Circle):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_square(self, square: Square):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def visit_triangle(self, triangle: Triangle):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# 具体Visitor实现
|
||||||
|
class ShapeVisitor(Visitor):
|
||||||
|
def visit_circle(self, circle: Circle):
|
||||||
|
print("Visiting Circle:", end=" ")
|
||||||
|
circle.claim_shape()
|
||||||
|
|
||||||
|
def visit_square(self, square: Square):
|
||||||
|
print("Visiting Square:", end=" ")
|
||||||
|
square.claim_shape()
|
||||||
|
|
||||||
|
def visit_triangle(self, triangle: Triangle):
|
||||||
|
print("Visiting Triangle:", end=" ")
|
||||||
|
triangle.claim_shape()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("========== 访问者模式 ==========")
|
||||||
|
shapes = [Circle(), Square(), Triangle()]
|
||||||
|
visitor = ShapeVisitor()
|
||||||
|
for shape in shapes:
|
||||||
|
shape.accept(visitor)
|
||||||
|
|
||||||
|
print("\n======== 访问者模式结束 ========")
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝申请报销款,需要走产品经理、部门经理和总经理的审核~
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Manager {
|
||||||
|
protected successor: Manager | null = null;
|
||||||
|
protected name: string;
|
||||||
|
protected amount: number = 0;
|
||||||
|
|
||||||
|
constructor(name: string) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSuccessor(successor: Manager) {
|
||||||
|
this.successor = successor;
|
||||||
|
console.log(`${this.name}的下一级经理是${successor.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAmountRight(amount: number) {
|
||||||
|
this.amount = amount;
|
||||||
|
console.log(`${this.name}的报销权限是${amount.toFixed(2)}元`);
|
||||||
|
}
|
||||||
|
|
||||||
|
haveRight(amount: number): boolean {
|
||||||
|
const right = amount <= this.amount;
|
||||||
|
if (right) {
|
||||||
|
console.log(`${this.name}有权限审批${amount.toFixed(2)}元的报销请求`);
|
||||||
|
} else {
|
||||||
|
console.log(`${this.name}没有权限审批${amount.toFixed(2)}元的报销请求`);
|
||||||
|
}
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
approve(name: string, amount: number) {
|
||||||
|
console.log(`${name}提交了一笔${amount.toFixed(2)}元的报销请求`);
|
||||||
|
if (this.haveRight(amount)) {
|
||||||
|
console.log(`${this.name}审批通过了${name}的报销请求,金额为${amount.toFixed(2)}元`);
|
||||||
|
} else if (this.successor) {
|
||||||
|
console.log(`${this.name}将${name}的报销请求上报给${this.successor.name}审批`);
|
||||||
|
this.successor.approve(name, amount);
|
||||||
|
} else {
|
||||||
|
console.log(`没有合适的经理审批${name}的报销请求,金额为${amount.toFixed(2)}元`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
console.log("========= 责任链模式 =========");
|
||||||
|
|
||||||
|
// 创建经理
|
||||||
|
const pm = new Manager("产品经理");
|
||||||
|
pm.setAmountRight(1000);
|
||||||
|
|
||||||
|
const dm = new Manager("部门经理");
|
||||||
|
dm.setAmountRight(5000);
|
||||||
|
|
||||||
|
const gm = new Manager("总经理");
|
||||||
|
gm.setAmountRight(20000);
|
||||||
|
|
||||||
|
// 设置责任链
|
||||||
|
pm.setSuccessor(dm);
|
||||||
|
dm.setSuccessor(gm);
|
||||||
|
|
||||||
|
// 提交报销请求
|
||||||
|
console.log("-----");
|
||||||
|
pm.approve("汤宝宝", 800);
|
||||||
|
console.log("-----");
|
||||||
|
pm.approve("汤宝宝", 3000);
|
||||||
|
console.log("-----");
|
||||||
|
pm.approve("汤宝宝", 15000);
|
||||||
|
console.log("-----");
|
||||||
|
pm.approve("汤宝宝", 25000);
|
||||||
|
|
||||||
|
console.log("\n======= 责任链模式结束 =======");
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝成为一国之王,手下有一个传令官和三个大臣,分别是内政大臣、外交大臣和军事大臣。
|
||||||
|
有一天,汤宝宝想要发布一个命令,传令官负责将命令传达给大臣们,大臣们根据命令的内容决定是否执行。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 接收者接口
|
||||||
|
interface Receiver {
|
||||||
|
perform(): void;
|
||||||
|
abort(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体接收者:内政大臣
|
||||||
|
class HomeSecretary implements Receiver {
|
||||||
|
isPerforming: boolean;
|
||||||
|
constructor() {
|
||||||
|
this.isPerforming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
perform(): void {
|
||||||
|
this.isPerforming = true;
|
||||||
|
console.log("内政大臣开始执行命令");
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(): void {
|
||||||
|
this.isPerforming = false;
|
||||||
|
console.log("内政大臣取消执行命令");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体接收者:外交大臣
|
||||||
|
class ForeignSecretary implements Receiver {
|
||||||
|
isPerforming: boolean;
|
||||||
|
constructor() {
|
||||||
|
this.isPerforming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
perform(): void {
|
||||||
|
this.isPerforming = true;
|
||||||
|
console.log("外交大臣开始执行命令");
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(): void {
|
||||||
|
this.isPerforming = false;
|
||||||
|
console.log("外交大臣取消执行命令");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体接收者:军事大臣
|
||||||
|
class MilitarySecretary implements Receiver {
|
||||||
|
isPerforming: boolean;
|
||||||
|
constructor() {
|
||||||
|
this.isPerforming = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
perform(): void {
|
||||||
|
this.isPerforming = true;
|
||||||
|
console.log("军事大臣开始执行命令");
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(): void {
|
||||||
|
this.isPerforming = false;
|
||||||
|
console.log("军事大臣取消执行命令");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 命令接口
|
||||||
|
interface Command {
|
||||||
|
execute(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
class PerformCommand implements Command {
|
||||||
|
receiver: Receiver;
|
||||||
|
|
||||||
|
constructor(receiver: Receiver) {
|
||||||
|
this.receiver = receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(): void {
|
||||||
|
this.receiver.perform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消命令
|
||||||
|
class AbortCommand implements Command {
|
||||||
|
receiver: Receiver;
|
||||||
|
|
||||||
|
constructor(receiver: Receiver) {
|
||||||
|
this.receiver = receiver;
|
||||||
|
}
|
||||||
|
execute(): void {
|
||||||
|
this.receiver.abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 传令官
|
||||||
|
class Herald {
|
||||||
|
private commands: Command[] = [];
|
||||||
|
|
||||||
|
addCommand(command: Command): void {
|
||||||
|
this.commands.push(command);
|
||||||
|
}
|
||||||
|
executeCommands(): void {
|
||||||
|
for (const command of this.commands) {
|
||||||
|
command.execute();
|
||||||
|
}
|
||||||
|
this.commands = []; // 执行完后清空命令列表
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("======= 命令模式开始 =======");
|
||||||
|
|
||||||
|
// 创建接收者
|
||||||
|
const homeSecretary = new HomeSecretary();
|
||||||
|
const foreignSecretary = new ForeignSecretary();
|
||||||
|
const defenseSecretary = new MilitarySecretary();
|
||||||
|
|
||||||
|
// 创建命令
|
||||||
|
const performHomeCommand = new PerformCommand(homeSecretary);
|
||||||
|
const abortHomeCommand = new AbortCommand(homeSecretary);
|
||||||
|
const performForeignCommand = new PerformCommand(foreignSecretary);
|
||||||
|
const abortForeignCommand = new AbortCommand(foreignSecretary);
|
||||||
|
const performDefenseCommand = new PerformCommand(defenseSecretary);
|
||||||
|
const abortDefenseCommand = new AbortCommand(defenseSecretary);
|
||||||
|
|
||||||
|
// 创建传令官
|
||||||
|
const herald = new Herald();
|
||||||
|
|
||||||
|
// 添加命令
|
||||||
|
herald.addCommand(performHomeCommand);
|
||||||
|
herald.addCommand(performForeignCommand);
|
||||||
|
herald.addCommand(performDefenseCommand);
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
|
herald.executeCommands();
|
||||||
|
|
||||||
|
// 取消命令
|
||||||
|
herald.addCommand(abortHomeCommand);
|
||||||
|
herald.addCommand(abortForeignCommand);
|
||||||
|
herald.addCommand(abortDefenseCommand);
|
||||||
|
|
||||||
|
// 执行取消命令
|
||||||
|
herald.executeCommands();
|
||||||
|
|
||||||
|
console.log("\n======= 命令模式结束 =======");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
实例
|
||||||
|
汤宝宝教你番茄炒蛋~
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TomatoEgg {
|
||||||
|
serve() {
|
||||||
|
console.log("番茄炒蛋上桌啦!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CutTomato {
|
||||||
|
cut() {
|
||||||
|
console.log("番茄切好了。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BeatEgg {
|
||||||
|
beat() {
|
||||||
|
console.log("鸡蛋打散了。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Cook {
|
||||||
|
private cutTomato: CutTomato;
|
||||||
|
private beatEgg: BeatEgg;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.cutTomato = new CutTomato();
|
||||||
|
this.beatEgg = new BeatEgg();
|
||||||
|
}
|
||||||
|
|
||||||
|
cookDish() {
|
||||||
|
this.cutTomato.cut();
|
||||||
|
this.beatEgg.beat();
|
||||||
|
console.log("食材放入锅中,开火加热。");
|
||||||
|
console.log("番茄炒蛋炒好了。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 外观
|
||||||
|
class ChefFacade {
|
||||||
|
private tomatoEgg: TomatoEgg;
|
||||||
|
private cook: Cook;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.tomatoEgg = new TomatoEgg();
|
||||||
|
this.cook = new Cook();
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareAndServe() {
|
||||||
|
console.log("准备食材...")
|
||||||
|
this.cook.cookDish();
|
||||||
|
this.tomatoEgg.serve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
console.log("============= 外观模式 =============")
|
||||||
|
const chef = new ChefFacade();
|
||||||
|
chef.prepareAndServe();
|
||||||
|
console.log("\n=========== 外观模式结束 ===========")
|
||||||
|
})()
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝开了一家服装租赁店,好多客人来店里租衣服~
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 享元抽象类 - 服装接口
|
||||||
|
interface ClothingInterface {
|
||||||
|
show(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 享元对象 - 服装
|
||||||
|
class Clothing implements ClothingInterface {
|
||||||
|
private style: string;
|
||||||
|
private size: string;
|
||||||
|
private color: string;
|
||||||
|
|
||||||
|
constructor(style: string, size: string, color: string) {
|
||||||
|
this.style = style;
|
||||||
|
this.size = size;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
console.log(
|
||||||
|
`服装款式: ${this.style}, 尺码: ${this.size}, 颜色: ${this.color}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 享元工厂 - 服装店
|
||||||
|
class ClothingFactory {
|
||||||
|
private clothingPool: { [key: string]: ClothingInterface };
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.clothingPool = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getClothing(style: string, size: string, color: string): ClothingInterface {
|
||||||
|
const key = `${style}-${size}-${color}`;
|
||||||
|
if (!this.clothingPool[key]) {
|
||||||
|
this.clothingPool[key] = new Clothing(style, size, color);
|
||||||
|
}
|
||||||
|
return this.clothingPool[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
showStock() {
|
||||||
|
console.log("\n服装库存:");
|
||||||
|
for (const key in this.clothingPool) {
|
||||||
|
console.log(`Key: ${key} ->`);
|
||||||
|
this.clothingPool[key].show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 客人
|
||||||
|
class Customer {
|
||||||
|
private name: string;
|
||||||
|
clothing: ClothingInterface[];
|
||||||
|
|
||||||
|
constructor(name: string) {
|
||||||
|
this.name = name;
|
||||||
|
this.clothing = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
rentClothing(clothing: ClothingInterface) {
|
||||||
|
console.log(`${this.name} 租了一件服装.`);
|
||||||
|
this.clothing.push(clothing);
|
||||||
|
clothing.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
showClothing() {
|
||||||
|
console.log(`\n客人${this.name}租赁的服装有:`);
|
||||||
|
this.clothing.forEach((c) => c.show());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 享元模式 =============");
|
||||||
|
const factory = new ClothingFactory();
|
||||||
|
|
||||||
|
// 客人1租衣服
|
||||||
|
const customer1 = new Customer("小红");
|
||||||
|
customer1.rentClothing(factory.getClothing("连衣裙", "M", "红色"));
|
||||||
|
customer1.rentClothing(factory.getClothing("牛仔裤", "L", "蓝色"));
|
||||||
|
|
||||||
|
// 客人2租衣服
|
||||||
|
const customer2 = new Customer("小明");
|
||||||
|
customer2.rentClothing(factory.getClothing("连衣裙", "M", "红色")); // 共享同一件连衣裙
|
||||||
|
customer2.rentClothing(factory.getClothing("夹克", "XL", "黑色"));
|
||||||
|
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
// 显示租赁情况
|
||||||
|
customer1.showClothing();
|
||||||
|
customer2.showClothing();
|
||||||
|
|
||||||
|
// 显示服装库存
|
||||||
|
factory.showStock();
|
||||||
|
|
||||||
|
console.log("\n=========== 享元模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
定义一种运算符,减号是加法,加号是减法。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象表达式
|
||||||
|
interface Expression {
|
||||||
|
interpret(): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 终结符表达式:数字
|
||||||
|
class NumberExpression implements Expression {
|
||||||
|
private token: string;
|
||||||
|
constructor(token: string) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
interpret(): number {
|
||||||
|
return parseInt(this.token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式:加法
|
||||||
|
class AddExpression implements Expression {
|
||||||
|
private left: Expression;
|
||||||
|
private right: Expression;
|
||||||
|
constructor(left: Expression, right: Expression) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
interpret(): number {
|
||||||
|
return this.left.interpret() - this.right.interpret();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式:减法
|
||||||
|
class SubExpression implements Expression {
|
||||||
|
private left: Expression;
|
||||||
|
private right: Expression;
|
||||||
|
constructor(left: Expression, right: Expression) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
interpret(): number {
|
||||||
|
return this.left.interpret() + this.right.interpret();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非终结符表达式工厂方法类型
|
||||||
|
type ExpressionFactory = (prev: Expression, next: string) => Expression;
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
private exp: string[];
|
||||||
|
private index: number;
|
||||||
|
private prev: Expression | null;
|
||||||
|
private factories: { [key: string]: ExpressionFactory };
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.exp = [];
|
||||||
|
this.index = 0;
|
||||||
|
this.prev = null;
|
||||||
|
this.factories = {
|
||||||
|
"-": (prev: Expression, next: string) =>
|
||||||
|
new SubExpression(prev, new NumberExpression(next)),
|
||||||
|
"+": (prev: Expression, next: string) =>
|
||||||
|
new AddExpression(prev, new NumberExpression(next)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
newNumberExpression(token: string): Expression {
|
||||||
|
return new NumberExpression(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(raw: string): Expression {
|
||||||
|
this.exp = raw.trim().split(/\s+/);
|
||||||
|
this.index = 0;
|
||||||
|
this.prev = null;
|
||||||
|
|
||||||
|
while (this.index < this.exp.length) {
|
||||||
|
let token = this.exp[this.index];
|
||||||
|
if (this.factories[token]) {
|
||||||
|
const factory = this.factories[token];
|
||||||
|
this.index++;
|
||||||
|
if (this.index >= this.exp.length) {
|
||||||
|
console.log("Last token is an operator, Ignored.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.prev === null) {
|
||||||
|
console.log(
|
||||||
|
"Expression cannot start with an operator, Initialized with 0."
|
||||||
|
);
|
||||||
|
this.prev = this.newNumberExpression("0");
|
||||||
|
}
|
||||||
|
token = this.exp[this.index];
|
||||||
|
this.prev = factory(this.prev, token);
|
||||||
|
} else {
|
||||||
|
this.prev = this.newNumberExpression(token);
|
||||||
|
}
|
||||||
|
this.index++;
|
||||||
|
}
|
||||||
|
if (this.prev === null) {
|
||||||
|
console.log("No valid expression parsed.");
|
||||||
|
return this.newNumberExpression("0");
|
||||||
|
}
|
||||||
|
return this.prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("========== 解释器模式 ==========");
|
||||||
|
const parser = new Parser();
|
||||||
|
let raw;
|
||||||
|
raw = "10 - 5";
|
||||||
|
console.log(`${raw} = ?`);
|
||||||
|
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||||
|
|
||||||
|
console.log("-----");
|
||||||
|
raw = "10 + 5";
|
||||||
|
console.log(`${raw} = ?`);
|
||||||
|
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||||
|
|
||||||
|
console.log("-----");
|
||||||
|
raw = "20 - 4 + 2 - 1";
|
||||||
|
console.log(`${raw} = ?`);
|
||||||
|
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||||
|
|
||||||
|
console.log("-----");
|
||||||
|
raw = " - 4 + 2 - ";
|
||||||
|
console.log(`${raw} = ?`);
|
||||||
|
console.log(`${raw} = ${parser.parse(raw).interpret()}`);
|
||||||
|
|
||||||
|
console.log("\n======== 解释器模式结束 ========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝有一张TODO表,记录着自己想干的事情。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 任务结构体 - 迭代器元素
|
||||||
|
interface Todo {
|
||||||
|
content: string;
|
||||||
|
done: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 迭代器接口
|
||||||
|
interface IIterator {
|
||||||
|
First(): Todo;
|
||||||
|
Next(): Todo;
|
||||||
|
isDone(): boolean;
|
||||||
|
CurrentItem(): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体迭代器 - 汤宝宝的TODO表迭代器
|
||||||
|
|
||||||
|
class TodoListIterator implements IIterator {
|
||||||
|
todoList: TodoList;
|
||||||
|
current: number;
|
||||||
|
constructor(todoList: TodoList) {
|
||||||
|
this.todoList = todoList;
|
||||||
|
this.current = 0;
|
||||||
|
}
|
||||||
|
First(): Todo {
|
||||||
|
this.current = 0;
|
||||||
|
return this.todoList.todos[this.current];
|
||||||
|
}
|
||||||
|
Next(): Todo {
|
||||||
|
this.current += 1;
|
||||||
|
return this.todoList.todos[this.current];
|
||||||
|
}
|
||||||
|
isDone(): boolean {
|
||||||
|
return this.current >= this.todoList.todos.length;
|
||||||
|
}
|
||||||
|
CurrentItem(): number {
|
||||||
|
if (this.current < 0 || this.current >= this.todoList.todos.length) {
|
||||||
|
return this.todoList.todos.length;
|
||||||
|
}
|
||||||
|
return this.current + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 集合接口
|
||||||
|
interface ICollection {
|
||||||
|
createIterator(): IIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体集合 - 汤宝宝的TODO表
|
||||||
|
class TodoList implements ICollection {
|
||||||
|
todos: Todo[];
|
||||||
|
constructor(todos: Todo[]) {
|
||||||
|
this.todos = todos;
|
||||||
|
}
|
||||||
|
|
||||||
|
createIterator(): IIterator {
|
||||||
|
return new TodoListIterator(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 迭代器模式 =============");
|
||||||
|
|
||||||
|
// 创建TODO表并添加任务
|
||||||
|
const todoList = new TodoList([
|
||||||
|
{ content: "学习Go语言", done: true },
|
||||||
|
{ content: "完成设计模式作业", done: false },
|
||||||
|
{ content: "锻炼身体", done: false },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 创建迭代器
|
||||||
|
const iterator = todoList.createIterator();
|
||||||
|
|
||||||
|
// 使用迭代器遍历TODO表
|
||||||
|
for (
|
||||||
|
let item = iterator.First();
|
||||||
|
!iterator.isDone();
|
||||||
|
item = iterator.Next()
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
`当前第 ${iterator.CurrentItem()} 项任务内容: ${
|
||||||
|
item ? item.content : ""
|
||||||
|
} 是否完成: ${item && item.done ? "已完成" : "未完成"}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("\n=========== 迭代器模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
他负责把房东和租客撮合在一起,帮他们达成租房协议。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象中介者
|
||||||
|
interface Mediator {
|
||||||
|
register(colleague: Colleague): void;
|
||||||
|
notify(sender: Colleague, event: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象同事
|
||||||
|
interface Colleague {
|
||||||
|
send(event: string): void;
|
||||||
|
receive(event: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体中介者
|
||||||
|
class HousingMediator implements Mediator {
|
||||||
|
private colleagues: Colleague[];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.colleagues = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
register(colleague: Colleague): void {
|
||||||
|
if (!this.colleagues.includes(colleague)) {
|
||||||
|
this.colleagues.push(colleague);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notify(sender: Colleague, event: string): void {
|
||||||
|
for (const colleague of this.colleagues) {
|
||||||
|
if (colleague !== sender) {
|
||||||
|
colleague.receive(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体同事 - 房东
|
||||||
|
class Landlord implements Colleague {
|
||||||
|
private mediator: Mediator;
|
||||||
|
private name: string;
|
||||||
|
|
||||||
|
constructor(mediator: Mediator, name: string) {
|
||||||
|
this.mediator = mediator;
|
||||||
|
this.name = name;
|
||||||
|
this.mediator.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
send(event: string): void {
|
||||||
|
console.log(`房东${this.name}发布信息: ${event}`);
|
||||||
|
this.mediator.notify(this, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
receive(event: string): void {
|
||||||
|
console.log(`房东${this.name}收到通知: ${event}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体同事 - 租客
|
||||||
|
class Tenant implements Colleague {
|
||||||
|
private mediator: Mediator;
|
||||||
|
private name: string;
|
||||||
|
|
||||||
|
constructor(mediator: Mediator, name: string) {
|
||||||
|
this.mediator = mediator;
|
||||||
|
this.name = name;
|
||||||
|
this.mediator.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
send(event: string): void {
|
||||||
|
console.log(`租客${this.name}发布需求: ${event}`);
|
||||||
|
this.mediator.notify(this, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
receive(event: string): void {
|
||||||
|
console.log(`租客${this.name}收到通知: ${event}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 中介者模式 =============");
|
||||||
|
const mediator = new HousingMediator();
|
||||||
|
|
||||||
|
const landlord1 = new Landlord(mediator, "张三");
|
||||||
|
const landlord2 = new Landlord(mediator, "李四");
|
||||||
|
const tenant1 = new Tenant(mediator, "王五");
|
||||||
|
const tenant2 = new Tenant(mediator, "赵六");
|
||||||
|
|
||||||
|
landlord1.send("张三有一套两室一厅的房子出租,月租2000元。");
|
||||||
|
console.log("-----");
|
||||||
|
tenant1.send("王五需要一套三室的房子,预算3000元/月。");
|
||||||
|
|
||||||
|
console.log("\n=========== 中介者模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝聘请了一位私人助理,帮助他管理日常事务。
|
||||||
|
他负责记录汤宝宝的状态,以便在需要时恢复到之前的状态。
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Tom {
|
||||||
|
state: string;
|
||||||
|
|
||||||
|
constructor(state: string) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
createMemento(): Memento {
|
||||||
|
console.log(`汤宝宝创建了备忘录,状态为: ${this.state}`);
|
||||||
|
return new Memento(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreMemento(memento: Memento): void {
|
||||||
|
this.state = memento.getState();
|
||||||
|
console.log(`汤宝宝恢复了状态: ${this.state}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Memento {
|
||||||
|
private state: string;
|
||||||
|
|
||||||
|
constructor(state: string) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
getState(): string {
|
||||||
|
return this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(state: string): void {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Assistant {
|
||||||
|
private mementos: Memento[];
|
||||||
|
constructor() {
|
||||||
|
this.mementos = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
backup(tom: Tom): void {
|
||||||
|
const memento = tom.createMemento();
|
||||||
|
this.mementos.push(memento);
|
||||||
|
console.log("私人助理备份了汤宝宝的状态");
|
||||||
|
}
|
||||||
|
|
||||||
|
undo(tom: Tom): void {
|
||||||
|
if (this.mementos.length === 0) {
|
||||||
|
console.log("没有备份可供恢复");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const memento = this.mementos.pop()!;
|
||||||
|
console.log("私人助理恢复了汤宝宝的状态");
|
||||||
|
tom.restoreMemento(memento);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 备忘录模式 =============");
|
||||||
|
const tom = new Tom("开心");
|
||||||
|
console.log(`汤宝宝的当前状态:${tom.state}`);
|
||||||
|
const assistant = new Assistant();
|
||||||
|
|
||||||
|
assistant.backup(tom);
|
||||||
|
tom.state = "生气";
|
||||||
|
console.log(`汤宝宝的当前状态:${tom.state}`);
|
||||||
|
|
||||||
|
assistant.undo(tom);
|
||||||
|
|
||||||
|
console.log("\n=========== 备忘录模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝一时想不开,当了房产中介。
|
||||||
|
一旦片区内有房东发布了新房源信息,他就会第一时间通知所有潜在租客。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 观察者抽象接口
|
||||||
|
interface Observer {
|
||||||
|
update(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 目标抽象接口
|
||||||
|
interface Subject {
|
||||||
|
attach(observer: Observer): void;
|
||||||
|
detach(observer: Observer): void;
|
||||||
|
notify(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体目标类
|
||||||
|
class HousingAgency implements Subject {
|
||||||
|
private observers: Observer[];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.observers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
attach(observer: Observer): void {
|
||||||
|
const isExist = this.observers.includes(observer);
|
||||||
|
if (isExist) {
|
||||||
|
return console.log("Observer has been attached already.");
|
||||||
|
}
|
||||||
|
this.observers.push(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
detach(observer: Observer): void {
|
||||||
|
const observerIndex = this.observers.indexOf(observer);
|
||||||
|
if (observerIndex === -1) {
|
||||||
|
return console.log("Nonexistent observer.");
|
||||||
|
}
|
||||||
|
this.observers.splice(observerIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
notify(): void {
|
||||||
|
console.log("房产中介通知了所有租客。");
|
||||||
|
for (const observer of this.observers) {
|
||||||
|
observer.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体观察者类
|
||||||
|
class TenantObs implements Observer {
|
||||||
|
private name: string;
|
||||||
|
|
||||||
|
constructor(name: string) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(): void {
|
||||||
|
console.log(`租客${this.name}收到了房源更新通知。`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 观察者模式 =============");
|
||||||
|
const agency = new HousingAgency();
|
||||||
|
const tenant1 = new TenantObs("小明");
|
||||||
|
const tenant2 = new TenantObs("小红");
|
||||||
|
console.log("小红和小明订阅了房产中介的房源信息。");
|
||||||
|
agency.attach(tenant1);
|
||||||
|
agency.attach(tenant2);
|
||||||
|
console.log("房源上新了!");
|
||||||
|
agency.notify();
|
||||||
|
|
||||||
|
console.log("-----");
|
||||||
|
console.log("小红不想再接收房源信息,退订了。");
|
||||||
|
agency.detach(tenant2);
|
||||||
|
console.log("又有新房源了!");
|
||||||
|
agency.notify();
|
||||||
|
|
||||||
|
console.log("\n=========== 观察者模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝买火车票,可以去火车站买,也可以去代售点买,但是汤宝宝选择全都要。然而,火车站总共只剩两张票,这可苦了小明了。
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface Seller {
|
||||||
|
sell(name: string): boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TrainStation implements Seller {
|
||||||
|
private stock: number;
|
||||||
|
|
||||||
|
constructor(stock: number) {
|
||||||
|
console.log(`火车站库存${stock}张票`);
|
||||||
|
this.stock = stock;
|
||||||
|
}
|
||||||
|
|
||||||
|
sell(name: string): boolean {
|
||||||
|
console.log(`${name}去火车站买票`);
|
||||||
|
if (this.stock > 0) {
|
||||||
|
this.stock--;
|
||||||
|
console.log(`${name}在火车站买到一张火车票。`);
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
console.log(`火车站没有票了, ${name}没买到票。`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TicketAgency implements Seller {
|
||||||
|
name: string;
|
||||||
|
private station: TrainStation;
|
||||||
|
|
||||||
|
constructor(name: string, station: TrainStation) {
|
||||||
|
this.name = name;
|
||||||
|
this.station = station;
|
||||||
|
}
|
||||||
|
|
||||||
|
sell(name: string): boolean {
|
||||||
|
console.log(`${name}去${this.name}买票`);
|
||||||
|
const result = this.station.sell(this.name);
|
||||||
|
if (result) {
|
||||||
|
console.log(`${name}在${this.name}买到一张火车票。`);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.log(`${name}在${this.name}没买到票。`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
console.log("============= 代理模式 =============");
|
||||||
|
const station = new TrainStation(2);
|
||||||
|
const agency = new TicketAgency("代售点A", station);
|
||||||
|
station.sell("汤宝宝");
|
||||||
|
agency.sell("汤宝宝");
|
||||||
|
console.log()
|
||||||
|
agency.sell("小明");
|
||||||
|
station.sell("小明");
|
||||||
|
console.log("\n=========== 代理模式结束 ===========");
|
||||||
|
|
||||||
|
})()
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
一个任务状态机
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Task {
|
||||||
|
state: State;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.state = new PendingState();
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(state: State) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle() {
|
||||||
|
this.state.handle(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态接口
|
||||||
|
interface State {
|
||||||
|
handle(task: Task): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 待处理
|
||||||
|
class PendingState implements State {
|
||||||
|
handle(task: Task): void {
|
||||||
|
console.log("任务待处理,开始处理任务...");
|
||||||
|
task.setState(new InProgressState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 进行中
|
||||||
|
class InProgressState implements State {
|
||||||
|
handle(task: Task): void {
|
||||||
|
console.log("任务进行中,完成任务...");
|
||||||
|
task.setState(new CompletedState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体状态 - 已完成
|
||||||
|
class CompletedState implements State {
|
||||||
|
handle(task: Task): void {
|
||||||
|
console.log("任务已完成,无法再处理。");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("============= 状态模式 =============");
|
||||||
|
const task = new Task();
|
||||||
|
task.handle();
|
||||||
|
task.handle();
|
||||||
|
task.handle();
|
||||||
|
console.log("\n=========== 状态模式结束 ===========");
|
||||||
|
})();
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝成为了收银员,消费者可以使用现金或者支付宝支付。
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface Strategy {
|
||||||
|
pay(amount: number): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CashStrategy implements Strategy {
|
||||||
|
pay(amount: number): string {
|
||||||
|
return `使用现金支付了${amount.toFixed(2)}元`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlipayStrategy implements Strategy {
|
||||||
|
pay(amount: number): string {
|
||||||
|
return `使用支付宝支付了${amount.toFixed(2)}元`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
private strategy: Strategy| null = null;
|
||||||
|
|
||||||
|
setStrategy(strategy: Strategy) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
pay(amount: number): string {
|
||||||
|
if (!this.strategy) {
|
||||||
|
throw new Error("支付策略未设置");
|
||||||
|
}
|
||||||
|
return this.strategy.pay(amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
console.log("=========== 策略模式 ===========")
|
||||||
|
const context = new Context();
|
||||||
|
|
||||||
|
context.setStrategy(new CashStrategy());
|
||||||
|
console.log(context.pay(100));
|
||||||
|
|
||||||
|
context.setStrategy(new AlipayStrategy());
|
||||||
|
console.log(context.pay(200));
|
||||||
|
|
||||||
|
console.log("\n========= 策略模式结束 =========")
|
||||||
|
})()
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝炒西红柿鸡蛋。
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class Dish {
|
||||||
|
abstract prepareIngredients(): string;
|
||||||
|
abstract cook(): string;
|
||||||
|
abstract serve(): string;
|
||||||
|
doCooking(): void {
|
||||||
|
console.log("第一步:", this.prepareIngredients());
|
||||||
|
console.log("第二步:", this.cook());
|
||||||
|
console.log("第三步:", this.serve());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TomatoEggs extends Dish {
|
||||||
|
prepareIngredients(): string {
|
||||||
|
return "准备西红柿和鸡蛋;";
|
||||||
|
}
|
||||||
|
cook(): string {
|
||||||
|
return "炒西红柿和鸡蛋;";
|
||||||
|
}
|
||||||
|
serve(): string {
|
||||||
|
return "装盘,西红柿鸡蛋炒好了。";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
console.log("========== 模板方法模式 ==========");
|
||||||
|
const dish = new TomatoEggs();
|
||||||
|
dish.doCooking();
|
||||||
|
console.log("\n======== 模板方法模式结束 ========");
|
||||||
|
})()
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
实例:
|
||||||
|
汤宝宝坚信搭积木是人类的未来,因此开办了一家积木厂。
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 抽象Node接口 Shape
|
||||||
|
interface Shape {
|
||||||
|
accept(visitor: Visitor): void;
|
||||||
|
claimShape(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Circle implements Shape {
|
||||||
|
accept(visitor: Visitor): void {
|
||||||
|
visitor.visitCircle(this);
|
||||||
|
}
|
||||||
|
claimShape(): string {
|
||||||
|
return "I am a Circle";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Square implements Shape {
|
||||||
|
accept(visitor: Visitor): void {
|
||||||
|
visitor.visitSquare(this);
|
||||||
|
}
|
||||||
|
claimShape(): string {
|
||||||
|
return "I am a Square";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Triangle implements Shape {
|
||||||
|
accept(visitor: Visitor): void {
|
||||||
|
visitor.visitTriangle(this);
|
||||||
|
}
|
||||||
|
claimShape(): string {
|
||||||
|
return "I am a Triangle";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象Visitor接口
|
||||||
|
interface Visitor {
|
||||||
|
visitCircle(circle: Circle): void;
|
||||||
|
visitSquare(square: Square): void;
|
||||||
|
visitTriangle(triangle: Triangle): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShapeVisitor implements Visitor {
|
||||||
|
visitCircle(circle: Circle): void {
|
||||||
|
console.log("Visiting Circle: ", circle.claimShape());
|
||||||
|
}
|
||||||
|
visitSquare(square: Square): void {
|
||||||
|
console.log("Visiting Square: ", square.claimShape());
|
||||||
|
}
|
||||||
|
visitTriangle(triangle: Triangle): void {
|
||||||
|
console.log("Visiting Triangle: ", triangle.claimShape());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
console.log("========== 访问者模式 ==========");
|
||||||
|
const shapes: Shape[] = [new Circle(), new Square(), new Triangle()];
|
||||||
|
const visitor: Visitor = new ShapeVisitor();
|
||||||
|
|
||||||
|
shapes.forEach((shape) => {
|
||||||
|
shape.accept(visitor);
|
||||||
|
});
|
||||||
|
console.log("\n======== 访问者模式结束 ========");
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user