设计模式学习笔记:创建型模式

闲来无事,再学习一波设计模式,后面的实现代码均使用TS。

创建型模式包括:工厂方法、抽象工厂、生成器、原型、单例

工厂方法

工厂方法是一种创建型设计模式, 解决了在不指定具体类的情况下创建产品对象的问题。

工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* The Creator class declares the factory method that is supposed to return an
* object of a Product class. The Creator's subclasses usually provide the
* implementation of this method.
*/
abstract class Creator {
/**
* Note that the Creator may also provide some default implementation of the
* factory method.
*/
public abstract factoryMethod(): Product;

/**
* Also note that, despite its name, the Creator's primary responsibility is
* not creating products. Usually, it contains some core business logic that
* relies on Product objects, returned by the factory method. Subclasses can
* indirectly change that business logic by overriding the factory method
* and returning a different type of product from it.
*/
public someOperation(): string {
// Call the factory method to create a Product object.
const product = this.factoryMethod();
// Now, use the product.
return `Creator: The same creator's code has just worked with ${product.operation()}`;
}
}

/**
* Concrete Creators override the factory method in order to change the
* resulting product's type.
*/
class ConcreteCreator1 extends Creator {
/**
* Note that the signature of the method still uses the abstract product
* type, even though the concrete product is actually returned from the
* method. This way the Creator can stay independent of concrete product
* classes.
*/
public factoryMethod(): Product {
return new ConcreteProduct1();
}
}

class ConcreteCreator2 extends Creator {
public factoryMethod(): Product {
return new ConcreteProduct2();
}
}

/**
* The Product interface declares the operations that all concrete products must
* implement.
*/
interface Product {
operation(): string;
}

/**
* Concrete Products provide various implementations of the Product interface.
*/
class ConcreteProduct1 implements Product {
public operation(): string {
return '{Result of the ConcreteProduct1}';
}
}

class ConcreteProduct2 implements Product {
public operation(): string {
return '{Result of the ConcreteProduct2}';
}
}

/**
* The client code works with an instance of a concrete creator, albeit through
* its base interface. As long as the client keeps working with the creator via
* the base interface, you can pass it any creator's subclass.
*/
function clientCode(creator: Creator) {
// ...
console.log('Client: I\'m not aware of the creator\'s class, but it still works.');
console.log(creator.someOperation());
// ...
}

/**
* The Application picks a creator's type depending on the configuration or
* environment.
*/
console.log('App: Launched with the ConcreteCreator1.');
clientCode(new ConcreteCreator1());
console.log('');

console.log('App: Launched with the ConcreteCreator2.');
clientCode(new ConcreteCreator2());

执行结果:

1
2
3
4
5
6
7
App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}