JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设原则、设计变化方向,环境相关等信息请查看设计模式开篇。
所有JAVA SCRIPT设计模式快捷连接:
创建型:(1) 抽象工厂 (2) 生成器 (3) 工厂方法 (4) 原型 (5) 单例
结构型:(6) 适配器 (7) 桥接 (8) 组合 (9) 装饰 (10) 外观 (11) 享元 (12) 代理
行为型:(13) 职责链 (14) 命令 (15) 解释器 (16) 迭代器 (17) 中介者 (18) 备忘录 (119) 观察者 (20) 状态 (21) 策略 (22) 模板方法 (23) 访问者
一、UML类图
参与者:
1.1 Context(环境,如TCPConnection)
- 定义客户感兴趣的接口。
- 维护一个ConcreteState子类的实例,这个实例定义当前状态。
1.2 State(状态,如TCPState)
- 定义一个接口以封装与Context的一个特定状态相关的行为。
1.3 ConcreteStatesubclasses(具体状态子类,如TCPEstablished,TCPListen,TCPClosed)
- 每一子类实现一个与Context的一个状态相关的行为。
二、意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
三、适用性
- 一个对象的行为取决于它的状态 , 并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常 , 有多个操作包含这一相同的条件结构。 State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
四、示例代码
4.1 动机
考虑一个表示网络连接的类TCPConnection。一个TCPConnection对象的状态处于若干不同状态之一:连接已建立(Established)、正在监听(Listening)、连接已关闭(Closed)。当一个
TCPConnection对象收到其他对象的请求时,它根据自身的当前状态作出不同的反应。例如,一个Open请求的结果依赖于该连接是处于连接已关闭状态还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。
这一模式的关键思想是引入了一个称为TCPState的抽象类来表示网络的连接状态。TCPState类为各表示不同的操作状态的子类声明了一个公共接口。TCPState的子类实现与特
定状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立状态和连接已关闭状态的行为。
TCPConnection类维护一个表示TCP连接当前状态的状态对象(一个TCPState子类的实例)。TCPConnection类将所有与状态相关的请求委托给这个状态对象。TCPConnection使用它的
TCPState子类实例来执行特定于连接状态的操作。
一旦连接状态改变,TCPConnection对象就会改变它所使用的状态对象。例如当连接从已建立状态转为已关闭状态时,TCPConnection会用一个TCPClosed的实例来代替原来的TCPEstablished的实例。
4.2 目录结构:
4.3 Context(环境,如TCPConnection)
- 定义客户感兴趣的接口。
- 维护一个ConcreteState子类的实例,这个实例定义当前状态。
import TCPOpen from './TCP/impl/TCPOpen.js';
export default class TCPConnection {
#state;
constructor() {
this.#state = TCPOpen.Instance();
}
Open() {
this.#state.Open(this);
}
Close() {
this.#state.Close(this);
}
Send()
{
this.#state.Send(this);
}
ChangeState(state)
{
this.#state =state;
}
}
4.4 State(状态,如TCPState)
- 定义一个接口以封装与Context的一个特定状态相关的行为。
export default class TCPstate {
constructor() {
}
/*打开链接*/
Open(tcpConnection)
{
}
/*关闭链接*/
Close(tcpConnection)
{
}
/*确认链接*/
Send(tcpConnection)
{
}
/*改变状态*/
ChageState(tcpConnection,state)
{
tcpConnection.ChangeState(state);
}
}
4.5 ConcreteStatesubclasses(具体状态子类,如TCPEstablished,TCPListen,TCPClosed)
- 每一子类实现一个与Context的一个状态相关的行为。
import TCPstate from '../TCPstate.js';
import TCPSend from './TCPSend.js';
/**
* 关闭状态
*/
export default class TCPOpen extends TCPstate {
static #instance;
constructor() {
super();
if (!TCPOpen.#instance) {
TCPOpen.#instance = this
}
return TCPOpen.#instance
}
static Instance() {
if (!this.#instance) this.#instance = new TCPOpen();
return this.#instance;
}
Open(tcpConnection)
{
console.log(`TCPOpen`);
this.ChageState(tcpConnection,TCPSend.Instance());
}
}
import TCPstate from '../TCPstate.js';
import TCPClosed from './TCPClosed.js';
/**
* 连接成功状态
*/
export default class TCPSend extends TCPstate {
static #instance;
constructor() {
super();
if (!TCPSend.#instance) {
TCPSend.#instance = this
}
return TCPSend.#instance
}
static Instance() {
if (!this.#instance) this.#instance = new TCPSend();
return this.#instance;
}
Send(tcpConnection) {
console.log(`TCPSend`);
this.ChageState(tcpConnection,TCPClosed.Instance());
}
}
import TCPstate from '../TCPstate.js';
/**
* 关闭状态
*/
export default class TCPClosed extends TCPstate {
static #instance;
constructor() {
super();
if (!TCPClosed.#instance) {
TCPClosed.#instance = this
}
return TCPClosed.#instance
}
static Instance() {
if (!this.#instance) this.#instance = new TCPClosed();
return this.#instance;
}
Close(tcpConnection)
{
console.log(`TCPClosed `);
this.ChageState(tcpConnection,null);
}
}
4.6 Client
import TCPConnection from './TCPConnection.js';
export default class Client{
constructor( ) {
let tcpConnection =new TCPConnection();
tcpConnection.Open();
tcpConnection.Send();
tcpConnection.Close();
}
}
4.7 测试HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="module">
import Client from './Client.js';
var canvas = document.getElementById("mycanvas")
var ctx = canvas.getContext("2d") //create 2d object
let cl = new Client();
</script>
</head>
<body>
<canvas id="mycanvas" width=900px height=900px></canvas>
</body>
</html>
测试结果:
TCPOpen.js:23 TCPOpen
TCPSend.js:23 TCPSend
TCPClosed.js:23 TCPClosed
五、源代码下载
下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw
提取码:q2ut