看看用TypeScript怎样实现常见的设计模式,顺便复习一下。

学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想记住就好。

这里尽量用原创的,实际中能碰到的例子来说明模式的特点和用处。

单例模式 Singleton

特点:在程序的生命周期内只有一个全局的实例,并且不能再new出新的实例。

用处:在一些只需要一个对象存在的情况下,可以使用单例,比如Cache, ThreadPool等。

注意:线程安全,当然,这在单线程的JavaScript环境里是不存在的。

下面用TypeScript写一个Cache来看看单例模式:

class Cache{
public static readonly Instance: Cache = new Cache(); private _items: {[key: string]: string} = {}; private Cache(){ } set(key: string, value: string){
this._items[key] = value;
console.log(`set cache with key: '${key}', value: '${value}'`);
} get(key: string): string{
let value = this._items[key];
console.log(`get cache value: '${value}' with key: '${key}'`);
return value;
}
} Cache.Instance.set('name', 'brook');
Cache.Instance.get('name');

输出:

set cache with key: 'name', value: 'brook'
get cache value: 'brook' with key: 'name'

很简单, 和C#基本一样, 设置一个全局只读的Instance并且把构造函数设为private,这样就确保了单例的特点。

可能有人有疑问:静态Instance在C#里能确保只有一个是CLR的功劳,这里每次访问Instance会不会重新new一个呢?

带着疑问来看看上面代码编译成JavaScript ES6的结果:

class Cache {
constructor() {
this._items = {};
}
Cache() {
}
set(key, value) {
this._items[key] = value;
console.log(`set cache with key: '${key}', value: '${value}'`);
}
get(key) {
let value = this._items[key];
console.log(`get cache value: '${value}' with key: '${key}'`);
return value;
}
}
Cache.Instance = new Cache();
Cache.Instance.set('name', 'brook');
Cache.Instance.get('name');

可以看到TypeScript的静态实例Instance其实是直接加到了Cache本身上面,当然也就确保了不会再new出新的来。

建造者模式 Builder

特点:一步一步来构建一个复杂对象,可以用不同组合或顺序建造出不同意义的对象,通常使用者并不需要知道建造的细节,通常使用链式调用来构建对象。

用处:当对象像积木一样灵活,并且需要使用者来自己组装时可以采用此模式,好处是不需要知道细节,调用方法即可,常用来构建如Http请求、生成器等。

注意:和工厂模式的区别,工厂是生产产品,谁生产,怎样生产无所谓,而建造者重在组装产品,层级不一样。

下面用TypeScript写一个Http的RequestBuilder来看看建造者模式:

enum HttpMethod{
GET,
POST,
} class HttpRequest {} //假设这是最终要发送的request class RequestBuilder{ private _method: HttpMethod; private _headers: {[key: string]: string} = {}; private _querys: {[key: string]: string} = {}; private _body: string; setMethod(method: HttpMethod): RequestBuilder{
this._method = method;
return this;
} setHeader(key: string, value: string): RequestBuilder{
this._headers[key] = value;
return this;
} setQuery(key: string, value: string): RequestBuilder{
this._querys[key] = value;
return this;
} setBody(body: string): RequestBuilder{
this._body = body;
return this;
} build(): HttpRequest {
// 根据上面信息生成HttpRequest
}
} let getRequest = new RequestBuilder()
.setMethod(HttpMethod.GET)
.setQuery('name', 'brook')
.build(); let postRequest = new RequestBuilder()
.setMethod(HttpMethod.POST)
.setHeader('ContentType', 'application/json')
.setBody('body')
.build();

上面RequestBuilder可以根据传进来的参数不同来构建出不同的HttpReqeust对象,这样使用者就可以按照自己需求来生成想要的对象。

这里有个问题是RequestBuilder需不需要抽象出来,个人觉得要看情况而定。

首先是保持简单,不去套UML,只是一个简单的构造功能给内部使用也没必要抽象来增加代码复杂度,但如果业务上这个Builder是封装在一个库里面并且要对外提供服务,那还是需要一个抽象来隐藏细节,消除对实现的依赖。

并且如果业务上还需要不同的RequestBuilder,比如说XmlRequestBuilder JsonRequestBuilder之类,那就更需要一个抽象了。

原型模式 Prototype

特点:不需要知道对象构建的细节,直接从对象上克隆出来。

用处:当对象的构建比较复杂时或者想得到目标对象相同内容的对象时可以考虑原型模式。

注意:深拷贝和浅拷贝。

JavaScript对这个应该是太了解了,天生就有Prototype,通过Object.create就可以根据对象原型创建一个新的对象。

class Origin{
name: string
} let origin = new Origin();
origin.name = 'brook'; let cloneObj = Object.create(origin);
console.log(cloneObj.name); // brook

不过还是用代码简单实现一下原型模式

interface Clonable<T>{
clone(): T;
} class Origin implements Clonable<Origin>{
name: string; clone(): Origin{
let target = new Origin();
target.name = this.name;
return target;
}
} let origin = new Origin();
origin.name = 'brook'; let cloneObj = origin.clone();
console.log(cloneObj.name); // brook

实现Clonable接口的都具有Clone功能,通过Clone功能就可以实现对象的快速复制,如果属性很多,想另外创建属性值也差不多相同的对象,原型就可以派上用场。

当然,还是要注意深拷贝和浅拷贝的问题,上面的代码只有string,所以浅拷贝没有问题,如果有对象就需要注意浅拷贝是否能满足要求。

TypeScript设计模式之单例、建造者、原型的更多相关文章

  1. java软件设计模式只单例设计模式

    概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计 ...

  2. Spring5源码解析-Spring框架中的单例和原型bean

    Spring5源码解析-Spring框架中的单例和原型bean 最近一直有问我单例和原型bean的一些原理性问题,这里就开一篇来说说的 通过Spring中的依赖注入极大方便了我们的开发.在xml通过& ...

  3. iOS 设计模式之单例

    设计模式:单例 一.  单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并 ...

  4. 设计模式——懒汉式单例类PK饿汉式单例类

    前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...

  5. 详略。。设计模式1——单例。。。。studying

    设计模式1--单例 解决:保证了一个类在内存中仅仅能有一个对象. 怎么做才干保证这个对象是唯一的呢? 思路: 1.假设其它程序可以任意用new创建该类对象,那么就无法控制个数.因此,不让其它程序用ne ...

  6. 游戏设计模式——C++单例类

    前言: 本文将探讨单例类设计模式,单例类的懒汉模式/饿汉模式,单例类的多线程安全性,最后将利用C++模板减少单例类代码量. 本文假设有一个Manager管理类,并以此为探究单例类的设计模式. 懒汉模式 ...

  7. 两种设计模式(2)==>>"单例"

    所谓“单例”: 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资 ...

  8. OC中的单例设计模式及单例的宏抽取

    // 在一个对象需要重复使用,并且很频繁时,可以对对象使用单例设计模式 // 单例的设计其实就是多alloc内部的allocWithZone下手,重写该方法 #pragma Person.h文件 #i ...

  9. [译]Java 设计模式之单例

    (文章翻译自Java Design Pattern: Singleton) 单例是在Java最经常被用到的设计模式.它通过阻止其他的实例化和修改来用于控制创建对象的数目.这一特性可应用于那些当只有一个 ...

随机推荐

  1. 会话Cookie及session的关系(Cookie & Session)

    会话Cookie及session的关系(Cookie & Session) 在通常的使用中,我们只知道session信息是存放在服务器端,而cookie是存放在客户端.但服务器如何使用sess ...

  2. shc加密shell脚本

    下载地址:http://www.datsi.fi.upm.es/~frosal/sources/ 安装 .tgz cd shc- mkdir -p /usr/local/man/man1 这步是必须的 ...

  3. OGG数据仓库以及单向复制(一)

    Item Source System Target System Platform OEL5.4 OEL5.4 Hostname gc1 oraclelinux54.cuug.net Database ...

  4. 在Java中打开浏览器

    try { Runtime.getRuntime().exec( "explorer http://www.baidu.com"); java.net.URI uri = new ...

  5. web下c#用jquery.tmpl.min.js插件实现分页查询_yginuo

    背景:webform或者mvc下实现插件快速分页 ps:我这里用的mvc开发的,数据库连接.用的ADO.NET实体数据模型 此案例下载地址(内含需要用到的一个插件与数据库):http://downlo ...

  6. 开源半成品的Web版工作流模板设计器(基于AngularJS 2和Redux), 还在继续填坑中

    先上个图: 很多企业内部的应用都需要有个工作流平台(插件),无奈灵活方便好用且能够自行更改代码定制嵌入的实在不多,只好自己动手慢慢搞. https://github.com/shibamo/99-fl ...

  7. WAS缓存导致的修改文件不生效问题【转】

    WAS缓存导致的修改文件不生效问题: 解决方法: 一. 修改web.xml文件,需要修改以下三个目录下的文件: 1. /opt/IBM/WebSphere/AppServer/profiles/Dmg ...

  8. SQL中如何使用EXISTS替代IN

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6385312.html 我们在程序中一般在做SQL优化的时候讲究使用EXISTS带替代IN的做 ...

  9. HUST 1541 Student’s question

    1541 - Student’s question 时间限制:1秒 内存限制:128兆 696 次提交 134 次通过 题目描述 YYis a student. He is tired of calc ...

  10. Apache常见功能实战详解

    Apache 是一款使用量排名第一的 web 服务器,LAMP 中的 A 指的就是它.由于其开源.稳定.安全等特性而被广泛使用.前边的一篇文章中已经记录过如何搭建 LAMP 架构,搭建仅是第一步,其中 ...