个访问子系统的统一入口,并不影响用户直接使用子系统类
4、缺点:
(1)不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性
(2)在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
5、适用环境:
(1)对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系
(2)当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问
(3)当客户端与子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性
// 子系统类
class Light {
private name: string;
constructor(name) {
this.name = name;
}
open(): void {
console.log(this.name + " opened!");
}
}
class Heater {
open(): void {
console.log("Heater opened!");
}
}
// 外观类,统一操作多个子系统
class Facade{
private light1: Light;
private light2: Light;
private light3: Light;
private heater: Heater;
constructor() {
this.light1 = new Light("light1");
this.light2 = new Light("light2");
this.light3 = new Light("light3");
this.heater = new Heater();
}
open(): void {
this.light1.open();
this.light2.open();
this.light3.open();
this.heater.open();
}
}
let facade: Facade = new Facade();
facade.open(); // light1 opened!
// light2 opened!
// light3 opened!
// Heater opened!
享元模式:
1、定义:运用共享技术来有効地支持大量细粒度对象的复用。它通过共享已经存在的对象来
大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率
2、模型结构:
(1)抽象享元类(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,
非享元的外部状态以参数的形式通过方法传入
(2)具体享元类(ConcreteFlyweight):实现抽象享元角色中所规定的接口
(3)非共享具体享元类(UnsharedConcreteFlyweight):不可共享的外部状态,以参数形式注入具体享元的相关方法中
(4)享元工厂类(FlyweightFactory):负责创建和管理享元角色。当客户对象请求一个享元对象时,
享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;
如果不存在的话,则创建一个新的享元对象
3、优点:
(1)享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份
(2)享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享
4、缺点:
(1)享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化
(2)读取享元模式的外部状态会使得运行时间稍微变长
5、适用环境:
(1)一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费
(2)大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态
(3)由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才值得使用享元模式
// 抽象享元类 Flyweight,书本
interface Book {
cell(): void;
}
// 具体享元类 ConcreteFlyweight,书名
class BookOrder implements Book {
private name: string;
constructor(name: string) {
this.name = name;
}
cell(): void {
console.log("Cell a book, named " + this.name);
}
}
// 享元工厂类 FlyweightFactory
class BookFactory {
// 享元池
private bookPools: Map<string, Book> = new Map<string, Book>();
// 和单例模式结合
private constructor() {}
private static factory: BookFactory = new BookFactory();
static getInstance(): BookFactory {
return this.factory;
}
getOrder(bookName: string): Book {
let order: Book = null;
// 如果存在该书,则从享元池中取出,否则新建一个书对象
if (this.bookPools.has(bookName)) {
order = this.bookPools.get(bookName);
} else {
order = new BookOrder(bookName);
this.bookPools.set(bookName, order);
}
return order;
}
// 返回创建对象的数目
getTotalObjs(): number {
return this.bookPools.size;
}
}
let orders: Book[] = new Array<Book>();
// 确保只有一个工厂对象
let factory: BookFactory = BookFactory.getInstance();
function takeOrders(bookName: string): void {
orders.push(factory.getOrder(bookName));