You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+55-16Lines changed: 55 additions & 16 deletions
Original file line number
Diff line number
Diff line change
@@ -1817,9 +1817,16 @@ const query = new QueryBuilder()
1817
1817
1818
1818
### Single Responsibility Principle (SRP)
1819
1819
1820
+
### 单一职责原则 (SRP)
1821
+
1820
1822
As stated in Clean Code, "There should never be more than one reason for a class to change". It's tempting to jam-pack a class with a lot of functionality, like when you can only take one suitcase on your flight. The issue with this is that your class won't be conceptually cohesive and it will give it many reasons to change. Minimizing the amount of times you need to change a class is important. It's important because if too much functionality is in one class and you modify a piece of it, it can be difficult to understand how that will affect other dependent modules in your codebase.
As stated by Bertrand Meyer, "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification." What does that mean though? This principle basically states that you should allow users to add new functionalities without changing existing code.
@@ -1915,7 +1927,7 @@ function makeHttpCall<T>(url: string): Promise<T> {
1915
1927
}
1916
1928
```
1917
1929
1918
-
**Good:**
1930
+
**好的:**
1919
1931
1920
1932
```ts
1921
1933
abstractclassAdapter {
@@ -1959,15 +1971,25 @@ class HttpRequester {
1959
1971
}
1960
1972
```
1961
1973
1962
-
**[⬆ back to top](#table-of-contents)**
1974
+
**[⬆ 返回目录](#目录)**
1963
1975
1964
1976
### Liskov Substitution Principle (LSP)
1965
1977
1978
+
### 里氏代换原则 (LSP)
1979
+
1966
1980
This is a scary term for a very simple concept. It's formally defined as "If S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.)." That's an even scarier definition.
1967
1981
1968
1982
The best explanation for this is if you have a parent class and a child class, then the base class and child class can be used interchangeably without getting incorrect results. This might still be confusing, so let's take a look at the classic Square-Rectangle example. Mathematically, a square is a rectangle, but if you model it using the "is-a" relationship via inheritance, you quickly get into trouble.
1969
1983
1970
-
**Bad:**
1984
+
这是针对一个非常简单的里面的一个恐怖意图, 它的正式定义是: “如果 S 是 T 的一个子类型, 那么类
1985
+
型为 T 的对象可以被类型为 S 的对象替换(例如, 类型为 S 的对象可作为类型为 T 的替代品)儿不需
@@ -2028,7 +2050,7 @@ const rectangles = [new Rectangle(), new Rectangle(), new Square()];
2028
2050
renderLargeRectangles(rectangles);
2029
2051
```
2030
2052
2031
-
**Good:**
2053
+
**好的:**
2032
2054
2033
2055
```ts
2034
2056
abstractclassShape {
@@ -2076,14 +2098,20 @@ const shapes = [new Rectangle(4, 5), new Rectangle(4, 5), new Square(5)];
2076
2098
renderLargeShapes(shapes);
2077
2099
```
2078
2100
2079
-
**[⬆ back to top](#table-of-contents)**
2101
+
**[⬆ 返回目录](#目录)**
2080
2102
2081
2103
### Interface Segregation Principle (ISP)
2082
2104
2105
+
### 接口隔离原则 (ISP)
2106
+
2083
2107
ISP states that "Clients should not be forced to depend upon interfaces that they do not use.". This principle is very much related to the Single Responsibility Principle.
2084
2108
What it really means is that you should always design your abstractions in a way that the clients that are using the exposed methods do not get the whole pie instead. That also include imposing the clients with the burden of implementing methods that they don’t actually need.
@@ -2121,7 +2149,7 @@ class EconomicPrinter implements SmartPrinter {
2121
2149
}
2122
2150
```
2123
2151
2124
-
**Good:**
2152
+
**好的:**
2125
2153
2126
2154
```ts
2127
2155
interfacePrinter {
@@ -2157,21 +2185,32 @@ class EconomicPrinter implements Printer {
2157
2185
}
2158
2186
```
2159
2187
2160
-
**[⬆ back to top](#table-of-contents)**
2188
+
**[⬆ 返回目录](#目录)**
2161
2189
2162
2190
### Dependency Inversion Principle (DIP)
2163
2191
2192
+
### 依赖反转原则 (DIP)
2193
+
2164
2194
This principle states two essential things:
2165
2195
2166
2196
1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
2167
2197
2168
2198
2. Abstractions should not depend upon details. Details should depend on abstractions.
2169
2199
2200
+
这个原则阐述了两个重要的事情:
2201
+
2202
+
1. 高级模块不应该依赖于低级模块, 两者都应该依赖与抽象;
2203
+
2. 抽象不应当依赖于具体实现, 具体实现应当依赖于抽象。
2204
+
2170
2205
This can be hard to understand at first, but if you've worked with Angular, you've seen an implementation of this principle in the form of Dependency Injection (DI). While they are not identical concepts, DIP keeps high-level modules from knowing the details of its low-level modules and setting them up. It can accomplish this through DI. A huge benefit of this is that it reduces the coupling between modules. Coupling is a very bad development pattern because it makes your code hard to refactor.
DIP is usually achieved by a using an inversion of control (IoC) container. An example of a powerful IoC container for TypeScript is [InversifyJs](https://www.npmjs.com/package/inversify)
2173
2210
2174
-
**Bad:**
2211
+
DIP 通常通过使用控制反转 (IoC) 容器来达到。 [InversifyJs](https://www.npmjs.com/package/inversify) 是 TypeScript 下的一个强大的 IoC 容器示例。
2212
+
2213
+
**不好的:**
2175
2214
2176
2215
```ts
2177
2216
import { readFileasreadFileCb } from'fs';
@@ -2206,7 +2245,7 @@ const reader = new ReportReader();
2206
2245
awaitreport=awaitreader.read('report.xml');
2207
2246
```
2208
2247
2209
-
**Good:**
2248
+
**好的:**
2210
2249
2211
2250
```ts
2212
2251
import { readFileasreadFileCb } from'fs';
@@ -2254,7 +2293,7 @@ const reader = new ReportReader(new JsonFormatter());
0 commit comments