Skip to content

Commit 2fcf23d

Browse files
committed
🚧 update some creational modal
1 parent af214c5 commit 2fcf23d

File tree

7 files changed

+417
-0
lines changed

7 files changed

+417
-0
lines changed

SOLID.md

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
- Single Responsibility Principle 单一职责原则
2+
3+
一个类只负责一件事,也就是把关联性强的内容聚合到一个类里面,不掺杂其它的影响。
4+
5+
- Open/Closed Principle 开放封闭原则
6+
7+
实体应该对扩展是开放的,对修改是封闭的。即可扩展(extension),不可修改(modification)。
8+
9+
- Liskov Substitution Principle 里式替换原则
10+
11+
一个对象在其出现的任何地方,都可以用子类实例做替换,并且不会导致程序的错误。
12+
13+
- Interface Segregation Principle 接口分离原则
14+
15+
一个类不应该强制让它继承它不需要的接口,可以将接口拆分更细粒度,有助于解耦。
16+
17+
- Dependency Inversion Principle 依赖倒置原则

creational/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## 创建型模式
2+
3+
- 简单工厂模式(simple-factory)
4+
5+
- 工厂方法模式(factory-method)
6+
7+
- 抽象工厂模式(abstract-factory)
8+
9+
- 生成器模式(builder)
10+
11+
- 原型模式(prototype)
12+
13+
- 单例模式(singleton)

creational/abstract-factory/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# Abstract Factory Pattern(抽象工厂模式)
2+
3+
- https://refactoringguru.cn/design-patterns/abstract-factory
+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* The Abstract Factory interface declares a set of methods that return
3+
* different abstract products. These products are called a family and are
4+
* related by a high-level theme or concept. Products of one family are usually
5+
* able to collaborate among themselves. A family of products may have several
6+
* variants, but the products of one variant are incompatible with products of
7+
* another.
8+
*/
9+
interface AbstractFactory {
10+
createProductA(): AbstractProductA;
11+
12+
createProductB(): AbstractProductB;
13+
}
14+
15+
/**
16+
* Concrete Factories produce a family of products that belong to a single
17+
* variant. The factory guarantees that resulting products are compatible. Note
18+
* that signatures of the Concrete Factory's methods return an abstract product,
19+
* while inside the method a concrete product is instantiated.
20+
*/
21+
class ConcreteFactory1 implements AbstractFactory {
22+
public createProductA(): AbstractProductA {
23+
return new ConcreteProductA1();
24+
}
25+
26+
public createProductB(): AbstractProductB {
27+
return new ConcreteProductB1();
28+
}
29+
}
30+
31+
/**
32+
* Each Concrete Factory has a corresponding product variant.
33+
*/
34+
class ConcreteFactory2 implements AbstractFactory {
35+
public createProductA(): AbstractProductA {
36+
return new ConcreteProductA2();
37+
}
38+
39+
public createProductB(): AbstractProductB {
40+
return new ConcreteProductB2();
41+
}
42+
}
43+
44+
/**
45+
* Each distinct product of a product family should have a base interface. All
46+
* variants of the product must implement this interface.
47+
*/
48+
interface AbstractProductA {
49+
usefulFunctionA(): string;
50+
}
51+
52+
/**
53+
* These Concrete Products are created by corresponding Concrete Factories.
54+
*/
55+
class ConcreteProductA1 implements AbstractProductA {
56+
public usefulFunctionA(): string {
57+
return 'The result of the product A1.';
58+
}
59+
}
60+
61+
class ConcreteProductA2 implements AbstractProductA {
62+
public usefulFunctionA(): string {
63+
return 'The result of the product A2.';
64+
}
65+
}
66+
67+
/**
68+
* Here's the the base interface of another product. All products can interact
69+
* with each other, but proper interaction is possible only between products of
70+
* the same concrete variant.
71+
*/
72+
interface AbstractProductB {
73+
/**
74+
* Product B is able to do its own thing...
75+
*/
76+
usefulFunctionB(): string;
77+
78+
/**
79+
* ...but it also can collaborate with the ProductA.
80+
*
81+
* The Abstract Factory makes sure that all products it creates are of the
82+
* same variant and thus, compatible.
83+
*/
84+
anotherUsefulFunctionB(collaborator: AbstractProductA): string;
85+
}
86+
87+
/**
88+
* These Concrete Products are created by corresponding Concrete Factories.
89+
*/
90+
class ConcreteProductB1 implements AbstractProductB {
91+
public usefulFunctionB(): string {
92+
return 'The result of the product B1.';
93+
}
94+
95+
/**
96+
* The variant, Product B1, is only able to work correctly with the variant,
97+
* Product A1. Nevertheless, it accepts any instance of AbstractProductA as
98+
* an argument.
99+
*/
100+
public anotherUsefulFunctionB(collaborator: AbstractProductA): string {
101+
const result = collaborator.usefulFunctionA();
102+
return `The result of the B1 collaborating with the (${result})`;
103+
}
104+
}
105+
106+
class ConcreteProductB2 implements AbstractProductB {
107+
public usefulFunctionB(): string {
108+
return 'The result of the product B2.';
109+
}
110+
111+
/**
112+
* The variant, Product B2, is only able to work correctly with the variant,
113+
* Product A2. Nevertheless, it accepts any instance of AbstractProductA as
114+
* an argument.
115+
*/
116+
public anotherUsefulFunctionB(collaborator: AbstractProductA): string {
117+
const result = collaborator.usefulFunctionA();
118+
return `The result of the B2 collaborating with the (${result})`;
119+
}
120+
}
121+
122+
/**
123+
* The client code works with factories and products only through abstract
124+
* types: AbstractFactory and AbstractProduct. This lets you pass any factory or
125+
* product subclass to the client code without breaking it.
126+
*/
127+
function clientCode(factory: AbstractFactory) {
128+
const productA = factory.createProductA();
129+
const productB = factory.createProductB();
130+
131+
console.log(productB.usefulFunctionB());
132+
console.log(productB.anotherUsefulFunctionB(productA));
133+
}
134+
135+
/**
136+
* The client code can work with any concrete factory class.
137+
*/
138+
console.log('Client: Testing client code with the first factory type...');
139+
clientCode(new ConcreteFactory1());
140+
141+
console.log('');
142+
143+
console.log(
144+
'Client: Testing the same client code with the second factory type...'
145+
);
146+
clientCode(new ConcreteFactory2());

creational/builder/Sample-5.ts

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* The Builder interface specifies methods for creating the different parts of
3+
* the Product objects.
4+
*/
5+
interface Builder {
6+
producePartA(): void;
7+
producePartB(): void;
8+
producePartC(): void;
9+
}
10+
11+
/**
12+
* The Concrete Builder classes follow the Builder interface and provide
13+
* specific implementations of the building steps. Your program may have several
14+
* variations of Builders, implemented differently.
15+
*/
16+
class ConcreteBuilder1 implements Builder {
17+
private product: Product1;
18+
19+
/**
20+
* A fresh builder instance should contain a blank product object, which is
21+
* used in further assembly.
22+
*/
23+
constructor() {
24+
this.reset();
25+
}
26+
27+
public reset(): void {
28+
this.product = new Product1();
29+
}
30+
31+
/**
32+
* All production steps work with the same product instance.
33+
*/
34+
public producePartA(): void {
35+
this.product.parts.push('PartA1');
36+
}
37+
38+
public producePartB(): void {
39+
this.product.parts.push('PartB1');
40+
}
41+
42+
public producePartC(): void {
43+
this.product.parts.push('PartC1');
44+
}
45+
46+
/**
47+
* Concrete Builders are supposed to provide their own methods for
48+
* retrieving results. That's because various types of builders may create
49+
* entirely different products that don't follow the same interface.
50+
* Therefore, such methods cannot be declared in the base Builder interface
51+
* (at least in a statically typed programming language).
52+
*
53+
* Usually, after returning the end result to the client, a builder instance
54+
* is expected to be ready to start producing another product. That's why
55+
* it's a usual practice to call the reset method at the end of the
56+
* `getProduct` method body. However, this behavior is not mandatory, and
57+
* you can make your builders wait for an explicit reset call from the
58+
* client code before disposing of the previous result.
59+
*/
60+
public getProduct(): Product1 {
61+
const result = this.product;
62+
this.reset();
63+
return result;
64+
}
65+
}
66+
67+
/**
68+
* It makes sense to use the Builder pattern only when your products are quite
69+
* complex and require extensive configuration.
70+
*
71+
* Unlike in other creational patterns, different concrete builders can produce
72+
* unrelated products. In other words, results of various builders may not
73+
* always follow the same interface.
74+
*/
75+
class Product1 {
76+
public parts: string[] = [];
77+
78+
public listParts(): void {
79+
console.log(`Product parts: ${this.parts.join(', ')}\n`);
80+
}
81+
}
82+
83+
/**
84+
* The Director is only responsible for executing the building steps in a
85+
* particular sequence. It is helpful when producing products according to a
86+
* specific order or configuration. Strictly speaking, the Director class is
87+
* optional, since the client can control builders directly.
88+
*/
89+
class Director {
90+
private builder: Builder;
91+
92+
/**
93+
* The Director works with any builder instance that the client code passes
94+
* to it. This way, the client code may alter the final type of the newly
95+
* assembled product.
96+
*/
97+
public setBuilder(builder: Builder): void {
98+
this.builder = builder;
99+
}
100+
101+
/**
102+
* The Director can construct several product variations using the same
103+
* building steps.
104+
*/
105+
public buildMinimalViableProduct(): void {
106+
this.builder.producePartA();
107+
}
108+
109+
public buildFullFeaturedProduct(): void {
110+
this.builder.producePartA();
111+
this.builder.producePartB();
112+
this.builder.producePartC();
113+
}
114+
}
115+
116+
/**
117+
* The client code creates a builder object, passes it to the director and then
118+
* initiates the construction process. The end result is retrieved from the
119+
* builder object.
120+
*/
121+
function clientCode(director: Director) {
122+
const builder = new ConcreteBuilder1();
123+
director.setBuilder(builder);
124+
125+
console.log('Standard basic product:');
126+
director.buildMinimalViableProduct();
127+
builder.getProduct().listParts();
128+
129+
console.log('Standard full featured product:');
130+
director.buildFullFeaturedProduct();
131+
builder.getProduct().listParts();
132+
133+
// Remember, the Builder pattern can be used without a Director class.
134+
console.log('Custom product:');
135+
builder.producePartA();
136+
builder.producePartC();
137+
builder.getProduct().listParts();
138+
}
139+
140+
const director = new Director();
141+
clientCode(director);

creational/factory-method/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# Factory Method Pattern(工厂方法模式)
2+
3+
- https://refactoringguru.cn/design-patterns/factory-method

0 commit comments

Comments
 (0)