Skip to content

Commit bf05ff2

Browse files
committed
feat(再看设计原则): add 单一职责原则,依赖倒置原则 article
1 parent 45aa3fa commit bf05ff2

File tree

9 files changed

+232
-0
lines changed

9 files changed

+232
-0
lines changed

doc/第三轮.org

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ e.g. most, commonlib
107107
** TODO 简化UML
108108

109109

110+
* TODO 完成遵循的设计原则
110111

111112

112113
* TODO 改错
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
案例代码均使用函数式编程
2+
3+
每个设计原则给两个函数式编程的案例
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-04-17T02:45:40.161Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="-vJxyMst_ZgTiFNyMLb_" version="14.6.13" type="device"><diagram id="86Xzktq_ODqwRnDaKCym" name="第 1 页">7Vjbbts4EP0aA92HFqYuvjyunHR3gXgRNAXafWQl2mJDaQxqHNv5+h1KpC6Wkjq7FdKH5CWao6FIzjk81mjir7LjH5rv0jUkQk28aXKc+FcTz2OM+fTPIKcKmS9ZBWy1TGxSA9zJR2HBqUX3MhFFJxEBFMpdF4whz0WMHYxrDYdu2gZUd9Yd34oecBdz1Ue/yATTCl148wb/U8ht6mZms2V1J+Mu2e6kSHkChxbkX0/8lQbA6io7roQyxXN1qcZ9fOJuvTAtcrxkwAH+Xv6Vrh8XH+/wfp0jm6/Ve+bZxeHJ7VgkVAAbgsYUtpBzdd2gkYZ9ngjz2ClFTc4NwI5ARuB3gXiybPI9AkEpZsrepRXr01cz/sN0WgP/lIDv+w64OtopqujUjm6FlplAoWvQiYfNKCyQa2wD1TbN3p4sn4UK2OtYPFMzq2iaYSvwmbxFTTKdDgG0Wn2icVoojvKhuw5uZbqt8xom6cKS+QJi7SIfuNrbmT4JnlC5zukuDjJTPDe8biBHx7xhhSu5zek6phKZQkcPQqOks/G7vYGG7yhOpUpu+An2phpU+fjeRVEKWj7SY7mjvk1MGHQy7sxIS6cWBeXcOnbYGbTmx07iDS/QAjEoxXeF/FZvIyOiZB4BImQ2qdxptQjfq9VhtieOz+ujz6cdENhjfnJGYOND4xre0mJpxzGCkSQQ9iTQI1/JkvgCNdzX/mZqtpFKrUCBOV45lElODUpscEALmUyS0h2KHY9lvv1cesF71iA35cArv0E+2TL4pakgR16xZihS/JtQt1BIlGCer6vcaAcyx7JUYTQJr0pE4wpy2gSXJVeC1HAQRhGXEfv0AeqzbekNg8vYXYzE7WyAWzoLPHmHIk5zQ0wEcP/bxKNMn03rUrTIp5JgTf4Z2S/nv/KCLtVBn2oDAY3dqPK3MCXViHyA/i7NEZV2Nf0QGsK9FcWsiX+ogdZhJz7G08TMu0wToTeSKOY9UXxui+HN+seyfv8C758Neb83lvcv3rz/f5zz+Yu9f4jdsbx/OeT99CpKdUDa17s30/+ppv+8GIZMf0gMs7FM3zXYr9bBBdQLtzo4Ri3df+rgei3bWUsnjhK/ugfQddUuhjZqZjKBm+gndn3MfX34Uds3e822zzUTr6aG0Au6/fxysRxTDewXV8PyVdXAej8VKyXNZs9F0iJzhBckLwg6L0i+bz78NH99D2XzIQ+dvrhOFDZf2Mp7re+U/vW/</diagram></mxfile>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-04-17T02:45:51.701Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="nrmItlzKhwcJAPa0b3Nk" version="14.6.13" type="device"><diagram id="b6orVKUq2GshwCTnj_ro" name="第 1 页">7Vldc5s4FP01nuk+pIMQYPux2En74O56msy0fdpRQQZtZOQR8ld//V6B+DLEdpIS58F5CTpcCd17ju6V5AGeLHefJVnFX0VI+cC2wt0ATwe2baPhCP5pZJ8jY8/KgUiyMIdQBdyz39SAhdmahTRtGCohuGKrJhiIJKGBamBESrFtmi0Eb351RSLaAu4DwtvodxaqOEdH9rDCv1AWxcWXkTfO3yxJYWw8SWMSim0NwrcDPJFCqPxpuZtQroNXxCXvd/fE23JikibqnA6z6T4iP4do8c/D/Sy++3dzN/dusJmb2hcO0xD8N00hVSwikRB+W6G+FOskpHpUC1qVzUyIFYAIwP+oUntDJlkrAVCslty8hQnL/Q/d/6NllcDPDMAYF8B0Zz6Rt/b11pxKtqSKyhIstIM8aKaKSFUHcje1b09Gz0CpWMuAHgmZY1RIZETVEbtRyTEsDipgtnIP/STlRLFNcx7EqDQq7Soi4cFw+QxewenLEus2aD1J6btjD+FX0pd1/SQl2dcMVoIlKq2NPNcAGJh8iUZuPqLJlt7Bkj4wH42tI+bwkH+/klHpyMuVZQK4IXxtgvCNkhAW4qHe0i1bcpJoYS1EogrpaZ0QzqIEngOgTy9hf0OlYpB0P5kXSgvOD2LGwxnZi7VmClQRPBYtPxaS/YZhSaG9umhcp2Fxr3saqUmags28UA46gL6SXcNwRlJlgEBwTlYp+1W6sQQRscQXSomlMco8zSeB7VK52j26O67dttRMhxtsNVlGRW3cVgXJwwaLG8XI6Sm9uC0RtOjnLKM+VVI8lqVTR23BOJ8ILnTqTkRmVOiB04XqUMOShWGWoNIVCVgSPWTp6AZVyCzrOMUV8s2EAWd5TRFFct40SZz8onwuUqaY0OPL3NY3qxOm7/oDd5ohUk1EAk4QlrFFQQ9bqjVxHrVPL6E234Ze1zmP3VFP3Hod3MJqIOEHRYM40cT4QjwObBjeSsSG1puUhjodaOSvgQ1DYWSVsaqpA2KmSnUcqOH5AsnTRVMLTlsLGoL5ygXP9mExyIomHfpo6sCH2E90QQNFgJOuj6r2SZHU8gEQ1p9oPPs80bh2T6oZtlTz0FTLtTr0Uh0cfLo4FPuCZnGw+yoOo2txeMU6Hz63OHSy21dxGHcVB9hJQxwU+PXhmvT/aNI/LoaOpN8pBq+vpF/kmoudMh17WD9noo+W9aLrg9aJ8+BESndM/SgGgOf8rsI1repLulF8aPDnDq3IEHjy1Op16+WN7hzQhdXg2k7zMmk8GvepBvTO1TC+qBqGl1YDatxBoZco4Q0vps5mFbmvpPVFN1OjsdPYZ+K3uGsqYlLbbkw406E9lFZNAj1ssm3nwHmsb66rv3YdRsOuOmz1tdZwK05/Vwfz68mrF1EMvXd38kLty9kW/dej17Pv/N/J2Qt13bpeD1+9Hb5OyKHH0xc0q9+F82Ja/bqOb/8H</diagram></mxfile>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-04-17T02:46:05.222Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="hXj_65X3BCmOkS5FsVlH" version="14.6.13" type="device"><diagram id="ueGl610fqqksXwIN_2Sk" name="第 1 页">7Vpdj9o4FP01SN2HQbGdZOCxAdqVOl2NOpXafVp5EkO8Y2KamAH66/c6cb5IGEKHDNUKXsAntmPfc3zv9RUDMlluP8Z0FX6WARMDbAXbAZkOMEbEQfClkV2GYITHGbKIeWB6lcAD/8kMaBl0zQOW1DoqKYXiqzroyyhivqphNI7lpt5tLkX9rSu6YA3gwaeiiX7jgQozdIRvS/xPxhdh/mbkmv0tad7Z7CQJaSA3FYjMBmQSS6myX8vthAltvdwu2bgPB54WC4tZpLoM+LTBo+XsRzT78WnDw38s+tGf36CRWZza5TtmARjANGWsQrmQERWzEvViuY4Cpqe1oFX2uZNyBSAC8F+m1M6wSddKAhSqpTBPWRS819xA0xc0SbifgR+4yLskisbKTIDc7HG1mS1br/WgOQyUyHXssxdsgAsyQMZMLpmKdzAuZoIq/lyfnxo5LYp+xdB7yeHN2DLadyzDe6782/oMsL8FU2ZQSRv8qKyihFIyTyAWZ297pmJtdvCF0YDFDbqTDV8KGmle5zJSOfOaAyr4ItIcgUlhJPGeWaw4nI335oHSfHt+yEVwR3dyrQ0PxPlPecsLZcx/wrS0jVfHrvV40CONqGKWQJ/7nE20B32m21rHO5ooA/hSCLpK+GOxjSVYmkeeVEouTad0p9kiCC7UpLfHti/rqakTM8Cu031DTHtTeg00NlhY8xj2YWnVVHGqBEhDAg3yBU+JT1Qsnwr/pm02h5M4kUIC69NIpp1yNQg2Vy1aWPIgSL1DsqI+jxZfU19wg0rkLh04JSXyxZiBpE5FUUUz1jRFgj4ycS8TrrjU88dZX2+lT0xqKscbONMUidVERrAJylOuGKhhw7QiuhF7ilcw9Dp2N3ZHPXFrt3ALZ4EG7x6lfPpjgN0BJsgqLFDhHCyhCs73OD6d9swF1Bm2mwxrSMLYuUi9fghiYVEL63V2PbDoxBo6mmc8gTYq20epr5xxoKE/Kbi4mxQc3JMWIB5eJIbD2r/r8UMH4Rz4OwXGo3EOTHNHnbV21dY9izmYQIcWAxZpwaOQOhZUkgKrmQM0coQzJgWOyTXTKP2S8ckrs4dXUe803MBX5oeRPqAe+IFrsO8p2BO3Hu2R24z22G1xAm5fTsC9BvtXeHjn1GDfSm5fwf5Cd7TCv9twd6n4dzS0LPIr/v3YnY5tufqeTwC/s2DimFb5Jt3IX3RGl5+XHI76fPuSLn986WCP7bME+65iQJcUw/mrAq47xHYtdmBChgSNrPyzFyF6rhOgi+sJkX094V/R0xlqSr+F5LrknAfC1ds4oHyZlVRjIjgz8qwKqUJ4DzkYtuvniBBraFU+Ldey27aMzOrLTqglJXNFlqhk31yn2nMKqsDuwjzIv/P7+++Wx4+s/1Eev1+kvbE75vHI6U02zcrtNZPvnsmjA4Qbgkcd+e0rlUdtRVkP3D1YQsHO3l1Ld4Nzlu6OyWHUTQ69XdvR7aXTr1rydTTxKnIsI7F6fa7zBa9Iqoq3vkmCZXdMsC6bXzVr+3/B+bsW9PpMBNxGQa+ZPr6xZ2jWdq95wAmO/0CRpveSHjTL/3Rkt/TyrzFk9h8=</diagram></mxfile>
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# 定义
2+
3+
高层模块不应该依赖低层模块,两者都应该依赖其抽象
4+
抽象不应该依赖细节
5+
细节应该依赖抽象
6+
7+
8+
# 补充说明
9+
10+
<!-- 如何分辨高层模块、低层模块? -->
11+
所谓的高层、低层模块是按照依赖的方向来定的,如模块1依赖模块2,则我们说模块1属于高层模块,模块2属于低层模块
12+
13+
14+
<!-- 在代码中,抽象、细节在代码中指的是什么? -->
15+
模块间应该抽象依赖于抽象
16+
实现模块之间不应该发生直接的依赖关系,其依赖关系应该是通过接口产生的;
17+
接口不依赖于实现模块;
18+
实现模块依赖接口
19+
20+
所以说,符合依赖倒置原则的编程可以看作是“面向接口编程”
21+
22+
23+
符合依赖倒置原则有下面的好处:
24+
- 减少模块之间的耦合性
25+
- 便于替换细节
26+
- 提高系统的稳定性
27+
- 降低并行开发引起的风险
28+
- 提高代码的可读性和可维护性
29+
30+
31+
32+
# 案例1
33+
34+
TODO tu
35+
上图是读者阅读技术书的领域模型
36+
37+
相关伪代码如下:
38+
TechnicalBook
39+
```ts
40+
type technicalBook = {
41+
getContent: () => string
42+
}
43+
44+
export let TechnicalBook: technicalBook = {
45+
getContent: () => {
46+
return "技术书的内容"
47+
}
48+
}
49+
```
50+
Reader
51+
```ts
52+
export let read = (technicalBook: technicalBook) => {
53+
let content = technicalBook.getContent()
54+
55+
...
56+
}
57+
```
58+
Client
59+
```ts
60+
Reader.read(TechnicalBook)
61+
```
62+
63+
如果增加小说书,读者既可以阅读技术书又可以阅读小说书,具体由Client决定让读者阅读哪本书
64+
修改后的领域模型如下:
65+
TODO tu
66+
67+
修改后的相关伪代码如下:
68+
TechnicalBook代码不变
69+
70+
NovelBook
71+
```ts
72+
type novelBook = {
73+
getContent: () => string
74+
}
75+
76+
export let NovelBook: novelBook = {
77+
getContent: () => {
78+
return "小说书的内容"
79+
}
80+
}
81+
```
82+
Reader
83+
```ts
84+
export let read = (technicalBook: technicalBook, novelBook: novelBook, needReadBook: string) => {
85+
let content = null
86+
87+
switch (needReadBook) {
88+
case "technical":
89+
content = technicalBook.getContent()
90+
break
91+
case "novel":
92+
default:
93+
content = novelBook.getContent()
94+
break
95+
}
96+
97+
...
98+
}
99+
```
100+
Client
101+
```ts
102+
//选择让读者读小说书
103+
Reader.read(TechnicalBook, NovelBook, "novel")
104+
```
105+
106+
我们可以看到,每增加一本书,Reader都会受影响
107+
我们将其改为符合依赖倒置原则,从而使Reader不受影响
108+
修改后的领域模型如下:
109+
TODO tu
110+
111+
现在Reader改为依赖Book这个接口,而不再依赖它的具体实现模块了
112+
这样做的好处是只要Book这个接口不变,它的实现模块的变化不会影响到Reader
113+
114+
115+
修改后的相关伪代码如下:
116+
Book
117+
```ts
118+
export interface Book {
119+
getContent(): string
120+
}
121+
```
122+
TechnicalBook
123+
```ts
124+
export let TechnicalBook: Book = {
125+
getContent: () => {
126+
return "技术书的内容"
127+
}
128+
}
129+
```
130+
NovelBook
131+
```ts
132+
export let NovelBook: Book = {
133+
getContent: () => {
134+
return "小说书的内容"
135+
}
136+
}
137+
```
138+
Reader
139+
```ts
140+
export let read = (book: Book) => {
141+
let content = book.getContent()
142+
143+
...
144+
}
145+
```
146+
Client
147+
```ts
148+
//选择让读者读小说书
149+
Reader.read(NovelBook)
150+
```
151+
152+
<!--
153+
154+
155+
156+
157+
158+
# 案例2 -->
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-04-17T02:02:22.989Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="bQjiZp3qGXUN2eX79w0X" version="14.6.13" type="device"><diagram id="YagxbB3KC2PYYdOba1ut" name="第 1 页">tZXBbqMwEIafBqk9dBWgSZNjTbLdldpVd1Npzy42YNV4kJk2SZ9+x2AgJK02OfSCmH/GDjP/ZyeIk3J7Z3lVPICQOogmYhvEyyCKFtczejph1wqzm6gVcqtEK4WDsFbv0osTr74qIetRIQJoVNVYTMEYmeJI49bCZlyWgR7/asVzeSSsU66P1b9KYNGq8+hm0H9IlRfdL4ezRZspeVfsO6kLLmCzJ8WrIE4sALZv5TaR2s2um0u77vsn2f7DrDR4yoLFXADeRRt7m77Bise/f8WLK2/GG9evvuEgiYJbpgxKm/FUupCxICIbY/IkZgzg5afJwDeFu25S9UaVmhuKWAYG1z4TUsy1yg29p9JtS8KbtKhoyLc+gVCRmhZKi3u+g1fXUI08fekiVoBV77Qt135PSlv0vMwno4q1W0myU62sqeaxm1J4ID3w7ajwntfohRS05lWtnvs2Sm5zZRggQumLmk7bj4jJUebHSe3J7ac+hb37dGoklBLtjkq6BR36/sSEsY83A3/RzGvFPnuLuefeM5/3ew9Y0Isn4wxKro8pOXRfq8b5Gi289CfFDS1TWieggWxfGmiKOhy0zPADGEolhG42q3iqTP7k4FhehYNy3yxcxoPyx4/BSRaQI29tcx5p/iz1I9QKFbj9bVvLKiDKm1FNWTBdNorFBAw1wVVjliQcNtIhcZqzn5+xY7u9vfMT3f0qb6cfeMtyic05X15c7h19StR9QomDFBfCpS6e6XF5xAdNDXs+Dng4H5H2vhjTcH1Mg5OA1ma6uXgLAkuaDwgZk8Bo+snk29QxESUUh0P8X0z2LgSy7AuxmZ94KXS3yRngUDj8LTW5vf/2ePUP</diagram></mxfile>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<mxfile host="Electron" modified="2023-04-17T02:02:37.200Z" agent="5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/14.6.13 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36" etag="QJsRWOWslEfVBrto5PNP" version="14.6.13" type="device"><diagram id="etf0rUSdH31EPTqmbMfn" name="第 1 页">7VjJbtswEP0aA+0hhnZLx0hOFzQBgqZA0lPBSLTFhtK4FB3b/foORWqzE9dparQH+2BoHofUcN6bIaGRmxTr94Is8ivIKB85VrYeudOR40RegP8K2GggmDgamAuWacjugBv2kxrQMuiSZbQaOEoALtliCKZQljSVA4wIAauh2wz48K0LMqc7wE1K+C56yzKZazR0Jh3+gbJ53rzZDiI9UpDG2eykykkGqx7kXozcRABI/VSsE8pV7pq86HnvnhltAxO0lIdMqD79uLq9S2L32yo/89fpY2V/OWvSXMlNs2OaYQKMCULmMIeS8IsOjQUsy4yqZS20Op9LgAWCNoLfqZQbwyZZSkAolwU3oxix2Nyp+WPPDRvgqxodW7bbANO1eYW2Nn3rmgpWUElFC2bnim407zmkDxp6xzjvHEw8doBmJYmQfYCumbxrfPH5ax2e4xuzi0UZTSg6eSpjz5JioAqWIqX7mDDiJmJO5R6/oJUOlhwFzIHY4DxBOZHscRgHMeKft37t1GtgGKFjmTp1gnAc+VH7C/UCpmjdIBhbXjca+cP19ebMkp0E8aEXYwfVwnyJSO1/LFJ/S6Qnge7xi44iUN91x7bdk+CWQKOx5RwkSiSBbHpuC+VQ7XlxZA1e5ZgDrNO4XvHvKl6/8pHwpUnYKHFG5zFGRsWMIE9oxsgudgPXVkTHAA8fyxnsVEq1YgUnpSqJGZSyKRqlYcLZvMTnlJa1TuNHKiTDs+/cDEhVKnGaM55dkg0sFe2oy/ShseIcBPuJy5KmavqyDa2Bx42aaXQpaIU+140M7S3oiqwHjpekkgZIgXOyqNh9u40CFcnKGKSEwjjVO9VBuE5bBmp7dL2/EHaF23TIyZYOfGOvumuBExgs710JwvB5rQ865UtF4uyKZJt8zmriKyngob2/qJzNsO8kwEF1pxJqp0YNnM7kE1ooWJbVjbVakJSV8y91Gz2zO+Synjh1O+SzyYJb92NJJNGsKYo4uaf8GiomGaj1hfaNTT1i+H488qc1ImQCJW6CsJorimpYUaWIw4h9vsR22TbshoeSeyRuvT9qAFPM8KkBHKkBHCoJOwiOJAr/VPCvKHjvvy744AluY7xo1ef69M3bXqXjQNUOsOztjggwNbIVwRbpL9eB7gFDyr1dyhUEOHfG6ztujuqh5RMyGNIdY4oTvGAr4p0Ebbuzf6uFXpE74TG1ER6mjcmxxDH5o9PgPK0r7XQeHOc88A69ANqedyRdhKcD4RVFP/mvD4ToqQOBZJmq7Df3+Hfq+6/v+7+RwIF933/5hQ/N7suv/mrQfT53L34B</diagram></mxfile>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# 定义
2+
3+
只有一个原因引起变化;
4+
一次只做一件事情
5+
6+
<!-- # 解释定义 -->
7+
8+
9+
10+
# 补充说明
11+
12+
如果一个模块或者函数做了多件事情,那么应该将其拆分
13+
14+
从函数名上就能看出该函数是否符合单一职责原则,如getAndSetData这个函数名一看就知道做了两件事情,所以应该将其拆分为getData、setData这两个函数
15+
16+
17+
如果一个函数做了多件事情,有下面的缺点:
18+
19+
- 任何一件事情的变化都会影响该函数
20+
- 用户调用该函数时,本能只预期它做某件事情,结果它实际上还做了其它的事情,这可能造成bug
21+
22+
23+
# 案例1
24+
25+
TODO tu
26+
上图是操作书的接口,它不符合单一职责原则。
27+
这是因为它的getBookID、setBookID是书的数据的操作,而它的addBook是书的行为的操作
28+
29+
应该将其拆分为两个接口,拆分后的接口如下图所示:
30+
TODO tu
31+
32+
BookData负责书的数据
33+
BookAction负责书的行为
34+
BookInfo实现BookData和BookAction
35+
36+
37+
# 案例2
38+
39+
40+
41+
```ts
42+
type userName = string
43+
44+
type phone = number
45+
46+
type changeUser = (newUserData: [userName, phone]) => void
47+
```
48+
上面是一个函数的签名
49+
从签名可知,该函数不符合单一职责原则
50+
这是因为它的形参是一个数组,它包含了多个修改用户的的值,这说明该函数做了多件事情
51+
52+
应该将其拆分为多个函数,拆分后的函数如下所示:
53+
```ts
54+
type userName = string
55+
56+
type phone = number
57+
58+
type changeUserName = (newUserName: userName) => void
59+
type changePhone = (newPhone: phone) => void
60+
```
61+
62+
63+
64+
65+

0 commit comments

Comments
 (0)