定义:运用共享技术有效地支持大量细粒度的对象
类比:就像在一个大型会议上,每个参会者都有一个名字牌,但他们的椅子和桌子是共享的。这样可以减少资源消耗
应用场景
- 需要生成大量相似对象
- 对象的大部分状态可以外部化并且共享
优缺点
- 优点
- 减少了内存消耗
- 提高性能
- 缺点
- 增加系统的复杂性
- 需要确保共享对象的状态是外部化且可共享的
实现代码
// 享元类
class Flyweight {
private sharedState: any;
constructor(sharedState: any) {
this.sharedState = sharedState;
}
public operation(uniqueState: any): void {
const s = JSON.stringify(this.sharedState);
const u = JSON.stringify(uniqueState);
console.log(`Flyweight: Displaying shared (${s}) and unique (${u}) state.`);
}
}
// 享元工厂
class FlyweightFactory {
private flyweights: { [key: string]: Flyweight } = <any>{};
constructor(initialFlyweights: string[][]) {
for (const state of initialFlyweights) {
this.flyweights[this.getKey(state)] = new Flyweight(state);
}
}
private getKey(state: string[]): string {
return state.join('_');
}
public getFlyweight(sharedState: string[]): Flyweight {
const key = this.getKey(sharedState);
if (!(key in this.flyweights)) {
console.log('FlyweightFactory: Can\'t find a flyweight, creating new one.');
this.flyweights[key] = new Flyweight(sharedState);
} else {
console.log('FlyweightFactory: Reusing existing flyweight.');
}
return this.flyweights[key];
}
public listFlyweights(): void {
const count = Object.keys(this.flyweights).length;
console.log(`\nFlyweightFactory: I have ${count} flyweights:`);
for (const key in this.flyweights) {
console.log(key);
}
}
}
// 客户端代码
const factory = new FlyweightFactory([
['Chevrolet', 'Camaro2018', 'pink'],
['Mercedes Benz', 'C300', 'black'],
['Mercedes Benz', 'C500', 'red'],
['BMW', 'M5', 'red'],
['BMW', 'X6', 'white'],
]);
factory.listFlyweights();
// 添加一个汽车到警察数据库
function addCarToPoliceDatabase(
ff: FlyweightFactory, plates: string, owner: string, brand: string, model: string, color: string,
) {
console.log('\nClient: Adding a car to database.');
const flyweight = ff.getFlyweight([brand, model, color]);
// 客户端将享元和独特的状态传递给享元对象的操作方法
flyweight.operation([plates, owner]);
}
addCarToPoliceDatabase(factory, 'CL234IR', 'James Doe', 'BMW', 'M5', 'red');
addCarToPoliceDatabase(factory, 'CL234IR', 'James Doe', 'BMW', 'X1', 'red');
factory.listFlyweights();