-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-search.xml
324 lines (154 loc) · 194 KB
/
local-search.xml
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Karnaugh Map</title>
<link href="/Electronic-Design-Automation/Logic-Synthesis/Logic%20Synthesis/"/>
<url>/Electronic-Design-Automation/Logic-Synthesis/Logic%20Synthesis/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="一karnaugh-map">一、Karnaugh Map</h1><h2 id="最小项">1.1 最小项</h2><p>最小项的定义:一个函数的某个<strong>乘积项</strong>包含了函数的全部变量,其中每个变量都以原变量或反变量的形式出现,且仅出现一次,则这个乘积项称为该函数的一个标准积项,通常称为最小项。</p><p>最小项的表示方法:通常用<span class="math inline">\(m_i\)</span>来表示最小项。</p><p>下标i的确定方式:把最小项中原变量记为1,反变量记为0,当变量顺序确定后,可以按顺序排列成一个二进制数,则与这个二进制数相对应的十进制数,就是这个最小项的下标i。</p><p><strong>Example:</strong></p><p>函数<span class="math inline">\(L(A,B,C)\)</span>的最小项为:</p><p><span class="math display">\[\overline{A}\overline{B}\overline{C}, \overline{A}\overline{B}C, \overline{A}B\overline{C}, \overline{A}BC, A\overline{B}\overline{C}, A\overline{B}C, AB\overline{C}, ABC\]</span></p><p>分别对应:</p><p><span class="math display">\[000, 001, 010, 011, 100, 101, 110, 111\]</span></p><p><span class="math inline">\(m_i\)</span>的表达方式:</p><p><span class="math display">\[m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7\]</span></p><p>最小项的的相邻性:任何两个最小项如果他们只有一个因子不同,其余因子都相同,则称这两个最小项为相邻最小项。</p><p><strong>Example</strong>:<span class="math inline">\(m_0\)</span>和<span class="math inline">\(m_1\)</span>具有相邻性,<span class="math inline">\(m_1\)</span>和<span class="math inline">\(m_2\)</span>却没有,因为他们有两个不同的因子。</p><p>相邻的两个最小项之和可以合并一项,消去一个变量。如:</p><p><span class="math display">\[m_0 + m_2 = \overline{A}\overline{B}\overline{C} + \overline{A}B\overline{C} = \overline{A}(\overline{B} + B)\overline{C} = \overline{A}\overline{C}\]</span></p><h2 id="卡诺图">1.2 卡诺图</h2><ul><li>一种描述逻辑函数特殊方格图。</li><li>每格代表一个最小项,上下左右相邻就具备相邻性。</li><li>有n个变量,最小项就有<span class="math inline">\(2^n\)</span>且卡诺图也由<span class="math inline">\(2^n\)</span>个格子构成。</li></ul><p>两变量卡诺图:</p><figure><img src="https://img-blog.csdnimg.cn/20190306215730593.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhaGFzdXN1,size_16,color_FFFFFF,t_70" alt="两变量卡诺图" /><figcaption>两变量卡诺图</figcaption></figure><p>三变量卡诺图:</p><p><img src="https://img-blog.csdnimg.cn/20190306220010596.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhaGFzdXN1,size_16,color_FFFFFF,t_70" /></p><p>逻辑函数<span class="math inline">\(F(A, B, C, D) = \sum m (0,1,2,5,7,8,10,11,14,15)\)</span>的卡诺图:</p><p><img src="https://img-blog.csdnimg.cn/20190306220704263.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhaGFzdXN1,size_16,color_FFFFFF,t_70" /></p><h2 id="逻辑函数的卡诺图化简法">1.3 逻辑函数的卡诺图化简法</h2><p>诺图相邻性的特点保证了几何相邻两方格所代表的最小项只有一个变量不同。因此,若相邻的方格都为1(简称1格)时,则对应的最小项就可以合并。合并的结果是消去这个不同的变量,只保留相同的变量。这是图形化简法的依据。</p><p>综上所述,卡诺图具备以下特性:</p><ol type="1"><li>卡诺图中两个相邻1格的最小项可以合并成一个与(加)项,并消去一个变量。</li><li>卡诺图中四个相邻1格的最小项可以合并成一个与(加)项,并消去两个变量。</li><li>卡诺图中八个相邻1格的最小项可以合并成一个与(加)项,并消去三个变量。</li></ol><p>利用这3点特性来接着看下面的例子:</p><p><img src="https://img-blog.csdnimg.cn/20190306221517963.png" /></p><p>上图两个相邻1格的最小项可以合并成一个与项,并消去一个变量,化简式子如下:</p><p><span class="math display">\[m_1 = m_5 = \overline{A}\overline{B}C + A\overline{B}C = (\overline{A} + A)\overline{B}C = \overline{B}C\]</span></p><p>根据上面3个特性再来看几个例子加深理解,以下是4个相邻1格的: <img src="https://img-blog.csdnimg.cn/20190306222100667.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhaGFzdXN1,size_16,color_FFFFFF,t_70" /></p><p><strong>Example:</strong></p><p><span class="math display">\[F(A,B,C) = \sum(1,2,3,6,7)\]</span></p><p>先画出卡诺图,然后转换十进制对应1,2,3,6,7的地方填入为1,其余填写为0(这个步骤有前面的知识点支撑,应该不难理解了。)</p><p><img src="https://img-blog.csdnimg.cn/20190306224020999.png" /></p><p>然后获得式子:<span class="math inline">\(F = (m_1 + m_3) + (m_2 + m_3 + m_6 + m_7)\)</span></p><p>即:</p><p><span class="math display">\[F = \overline{A}C + B\]</span></p><p>首先,有这么几点需要明确:</p><ol type="1"><li>列出逻辑函数的最小项表达式,由最小项表达式确定变量的个数(如果最小项中缺少变量,应按例的方法补齐)。</li><li>画出最小项表达式对应的卡诺图。</li><li>将卡诺图中的1格画圈,一个也不能漏圈,否则最后得到的表达式就会与所给函数不等;1格允许被一个以上的圈所包围。</li><li>圈的个数应尽可能得少。即在保证1格一个也不漏圈的前提下,圈的个数越少越好。因为一个圈和一个与项相对应,圈数越少,与或表达式的与项就越少。</li><li>按照2k个方格来组合(即圈内的1格数必须为1,2,4,8等),圈的面积越大越好。因为圈越大,可消去的变量就越多,与项中的变量就越少。</li><li>每个圈应至少包含一个新的1格,否则这个圈是多余的。</li><li>用卡诺图化简所得到的最简与或式不是唯一的。</li></ol><h2 id="reference">Reference</h2><p><a href="https://blog.csdn.net/hahasusu/article/details/88244155">https://blog.csdn.net/hahasusu/article/details/88244155</a></p>]]></content>
<categories>
<category>Electronic Design Automation</category>
<category>Logic Synthesis</category>
</categories>
</entry>
<entry>
<title>Design Pattern</title>
<link href="/Programming/Python/Design%20Pattern/"/>
<url>/Programming/Python/Design%20Pattern/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="一面向对象设计原则">一、面向对象设计原则</h1><h2 id="依赖倒置原则dip">依赖倒置原则(DIP)</h2><ul><li>高层模块(稳定)不应该依赖(编译时依赖)于底层模块(变化),二者都应该依赖于抽象(稳定)。</li><li>抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。</li></ul><h2 id="开放封闭原则">开放封闭原则</h2><ul><li>对拓展开放,对更改封闭</li><li>类模块是可扩展的,但是不可修改。</li></ul><h2 id="单一职责原则srp">单一职责原则(SRP)</h2><ul><li>一个类应该仅有一个引起它变化的原因。</li><li>变化的方向隐含着类的责任。</li></ul><h2 id="liskov替换原则lsp">Liskov替换原则(LSP)</h2><ul><li>子类必须能够替换它们的基类(IS-A)。</li><li>继承表达类型抽象</li></ul><h2 id="接口隔离原则isp">接口隔离原则(ISP)</h2><ul><li>不应该强迫客户程序依赖它们不用的方法。</li><li>接口应该小而完备。</li></ul><h2 id="优先使用组合而不是继承">优先使用组合而不是继承</h2><ul><li>类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。</li><li>继承在某种程度上破坏了封装性,子类父类耦合度高。</li><li>对象组合则只要求被组合的对象具有良好的定义的接口,耦合度低。</li></ul><h2 id="封装变化点">封装变化点</h2><ul><li>使用封装来创建对象之间的分界层,让设计者可以对分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。</li></ul><h2 id="针对接口编程而不是针对实现编程">针对接口编程,而不是针对实现编程</h2><ul><li>不将变量类型声明为某个特定的具体类,而是声明为某个接口。</li><li>客户程序无需获知对象的具体类型,只需要知道对象所具有的接口。</li><li>减少系统中各部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案。</li></ul><h1 id="二模板方法">二、模板方法</h1><p><strong>Motivation:</strong> 如何在确定稳定操作结构的前提下,灵活应对各个子步骤的变化或者晚期实现需求?</p><p><strong>Definition:</strong> 定义一个操作中的算法骨架(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义overeide该算法的某些特定步骤。</p><p>Case1:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Lib</span>{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step1</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step3</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step5</span><span class="hljs-params">()</span></span>{}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">step2</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step4</span><span class="hljs-params">()</span></span>{}<br>};<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-function">Lib <span class="hljs-title">lib</span><span class="hljs-params">()</span></span>;<br> <span class="hljs-function">App <span class="hljs-title">app</span><span class="hljs-params">()</span></span>;<br> lib.<span class="hljs-built_in">step1</span>();<br> <span class="hljs-keyword">if</span>(app.<span class="hljs-built_in">step2</span>()) {<br> lib.<span class="hljs-built_in">step3</span>();<br> }<br><br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">4</span>; ++ i) {<br> app.<span class="hljs-built_in">step4</span>();<br> }<br> lib.<span class="hljs-built_in">step5</span>();<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><br></code></pre></td></tr></table></figure><p>Case2:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Lib</span>{<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-comment">// Stable template method</span><br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">run</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-built_in">step1</span>();<br> <span class="hljs-keyword">if</span>(<span class="hljs-built_in">step2</span>()) { <span class="hljs-comment">// Support for changes due to Polymorphism</span><br> <span class="hljs-built_in">step3</span>();<br> }<br><br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">4</span>; ++ i) {<br> <span class="hljs-built_in">step4</span>(); <span class="hljs-comment">// Support for changes due to Polymorphism</span><br> }<br> <span class="hljs-built_in">step5</span>();<br> }<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">Lib</span>(){}<br><br><span class="hljs-keyword">protected</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step1</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step3</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">step5</span><span class="hljs-params">()</span></span>{}<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">bool</span> <span class="hljs-title">step2</span><span class="hljs-params">()</span></span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">step4</span><span class="hljs-params">()</span></span>{}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">App</span> : <span class="hljs-keyword">public</span> Lib{<br><span class="hljs-keyword">protected</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">bool</span> <span class="hljs-title">step2</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">step4</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br>};<br><br><span class="hljs-function"><span class="hljs-type">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{<br> Lib* lib = <span class="hljs-keyword">new</span> <span class="hljs-built_in">App</span>();<br> lib-><span class="hljs-built_in">run</span>();<br> <span class="hljs-keyword">delete</span> lib;<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br><br></code></pre></td></tr></table></figure><p><strong>Conclution:</strong><br />- Make it a habit to recognize which function is variable and which is stable. - Template method is common. - The virtual functions are often set to protected.</p><h1 id="三策略模式">三、策略模式</h1><p><strong>Motivaiton:</strong> 某些对象的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使的对象很复杂。</p><p><strong>Definition:</strong> 定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换(变化)。该模式使得算法可以独立于使用它的客户程序(稳定)而变化(拓展,子类化)。</p><p><strong>Case1</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">enum</span> <span class="hljs-title class_">TaxBase</span> {<br> CN_Tax,<br> US_Tax,<br> DE_Tax,<br> <span class="hljs-comment">// change: TR_Tax</span><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SalesOrder</span>{<br> TaxBase tax;<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">double</span> <span class="hljs-title">CalculateTax</span><span class="hljs-params">()</span></span>{<br> <span class="hljs-keyword">if</span> (tax == CN_Tax) {}<br> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tax == US_Tax) {}<br> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (tax == DE_Tax) {}<br> <span class="hljs-comment">// change: else if (tax == FR_Tax) {}</span><br> }<br>}<br><br></code></pre></td></tr></table></figure><p><strong>Case2</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">TaxStrategy</span>{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">double</span> <span class="hljs-title">Calculate</span><span class="hljs-params">(<span class="hljs-type">const</span> Context& context)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">TaxStrategy</span>() {}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CNTax</span> : <span class="hljs-keyword">public</span> TaxStrategy {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">double</span> <span class="hljs-title">Calculate</span><span class="hljs-params">(<span class="hljs-type">const</span> Context& context)</span> </span>{}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">USTax</span> : <span class="hljs-keyword">public</span> TaxStrategy {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">double</span> <span class="hljs-title">Calculate</span><span class="hljs-params">(<span class="hljs-type">const</span> Context& context)</span> </span>{}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">DETax</span> : <span class="hljs-keyword">public</span> TaxStrategy {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">double</span> <span class="hljs-title">Calculate</span><span class="hljs-params">(<span class="hljs-type">const</span> Context& context)</span> </span>{}<br>};<br><br><span class="hljs-comment">// extend:</span><br><span class="hljs-comment">// class FRTax : public TaxStrategy {</span><br><span class="hljs-comment">// public:</span><br><span class="hljs-comment">// virtual double Calculate(const Context& context) {}</span><br><span class="hljs-comment">// };</span><br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SalesOrder</span> {<br><span class="hljs-keyword">private</span>:<br> TaxStrategy* strategy;<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">SalesOrder</span>(StrategyFactory* strategyFactory) {<br> <span class="hljs-keyword">this</span>->strategy = strategyFactory-><span class="hljs-built_in">NewStrategy</span>();<br> }<br> ~<span class="hljs-built_in">SalesOrder</span>(){<br> <span class="hljs-keyword">delete</span> <span class="hljs-keyword">this</span>->strategy;<br> }<br><br> <span class="hljs-function"><span class="hljs-type">double</span> <span class="hljs-title">CalculateTax</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-function">Context <span class="hljs-title">conttext</span><span class="hljs-params">()</span></span>;<br> <br> <span class="hljs-type">double</span> val = strategy-><span class="hljs-built_in">Calculate</span>(context);<br> } <br>}<br><br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong></p><ul><li>Strategy pattern provides a series of re-used algorithms to make switching alogrithms more convenient.</li><li>Strategy pattern can substitude condition statement unless the conditions are countable.</li><li>Single instance pattern can be used to reduce overhead</li></ul><h1 id="四观察者模式">四、观察者模式</h1><p><strong>Motivation:</strong> - 为某些对象简历通知依赖关系,即,一个对象的状态发生改变,所有的依赖对象都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。 - 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系,从而实现软件体系结构的松耦合。</p><p><strong>Definition:</strong> 定义对象间的一对多(变化)的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。</p><p><strong>Case1:</strong> Betray DIP, and the progressBar might be changed with aternaltive form in the future.</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">FileSplitter</span> {<br> string m_filePath;<br> <span class="hljs-type">int</span> m_fileNumber;<br> ProgressBar* m_progressBar; <span class="hljs-comment">// New requirement</span><br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">FileSplitter</span>(<span class="hljs-type">const</span> string & filePath, <span class="hljs-type">int</span> fileNumber, ProgressBar* progressBar) :<br> <span class="hljs-built_in">m_filePath</span>(filePath),<br> <span class="hljs-built_in">m_fileNumber</span>(fileNumber),<br> <span class="hljs-built_in">m_progressBar</span>(progressBar) {}<br> <br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-comment">// 1. 读取大文件</span><br><br> <span class="hljs-comment">// 2.分批次向小文件写入</span><br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < m_fileNumber; ++i) {<br> <span class="hljs-comment">// ...</span><br> <span class="hljs-keyword">if</span> (m_progressBar) {<br> m_progressBar-><span class="hljs-built_in">setValue</span>((i + <span class="hljs-number">1</span>) / m_fileNumber); <span class="hljs-comment">// Update progressbar</span><br> }<br> }<br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MainForm</span> : <span class="hljs-keyword">public</span> Form<br>{<br> TextBox* txtFilePath;<br> TextBox* txtFileNumber;<br> ProgressBar* progressBar; <span class="hljs-comment">// New requirement</span><br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Button1_Click</span><span class="hljs-params">()</span> </span>{<br> string filePath = txtFilePath-><span class="hljs-built_in">getText</span>();<br> <span class="hljs-type">int</span> number = <span class="hljs-built_in">atoi</span>(txtFileNumber-><span class="hljs-built_in">getText</span>().<span class="hljs-built_in">c_str</span>());<br><br> <span class="hljs-function">FileSplitter <span class="hljs-title">splitter</span><span class="hljs-params">(filePath, number, progressBar)</span></span>;<br> splitter.<span class="hljs-built_in">split</span>();<br> }<br>}<br></code></pre></td></tr></table></figure><p><strong>Case2:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><br><span class="hljs-comment">// Observer</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IProgress</span>{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DoProgress</span><span class="hljs-params">(<span class="hljs-type">float</span> value)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">IProgress</span>(){}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">FileSplitter</span> {<br> string m_filePath;<br> <span class="hljs-type">int</span> m_fileNumber;<br> <span class="hljs-comment">// ProgressBar* m_progressBar; </span><br> list<IProgress*> m_iprogressList; <span class="hljs-comment">// 抽象通知机制,支持多个观察者</span><br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">FileSplitter</span>(<span class="hljs-type">const</span> string & filePath, <span class="hljs-type">int</span> fileNumber) :<br> <span class="hljs-built_in">m_filePath</span>(filePath),<br> <span class="hljs-built_in">m_fileNumber</span>(fileNumber) {}<br> <br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">add_IProgress</span><span class="hljs-params">(IProgress* iprogress)</span> </span>{<br> m_iprogressList.<span class="hljs-built_in">add</span>(iprogress);<br> }<br><br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">remove_IProgress</span><span class="hljs-params">(IProgress* iprogress)</span> </span>{<br> m_iprogressList.<span class="hljs-built_in">remove</span>(iprogress);<br> }<br><br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-comment">// 1. 读取大文件</span><br><br> <span class="hljs-comment">// 2.分批次向小文件写入</span><br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i < m_fileNumber; ++i) {<br> <span class="hljs-comment">// ...</span><br> <span class="hljs-type">float</span> progressValue = m_fileNumber;<br> progressValue = (i + <span class="hljs-number">1</span>) / progressValue;<br> <span class="hljs-built_in">onProgress</span>(progressValue); <span class="hljs-comment">// 发送通知</span><br> }<br> }<br> <br><span class="hljs-keyword">protected</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">onProgress</span><span class="hljs-params">(<span class="hljs-type">float</span> value)</span> </span>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">auto</span> &iter : m_iprogressList) {<br> iter-><span class="hljs-built_in">DoProgress</span>(progressValue); <span class="hljs-comment">// Update progressbar</span><br> }<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MainForm</span> : <span class="hljs-keyword">public</span> Form, <span class="hljs-keyword">public</span> IProgress <span class="hljs-comment">// C++ 多继承一般第一个是父类,其他的是接口</span><br>{<br> TextBox* txtFilePath;<br> TextBox* txtFileNumber;<br> ProgressBar* progressBar; <span class="hljs-comment">// New requirement</span><br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Button1_Click</span><span class="hljs-params">()</span> </span>{<br> string filePath = txtFilePath-><span class="hljs-built_in">getText</span>();<br> <span class="hljs-type">int</span> number = <span class="hljs-built_in">atoi</span>(txtFileNumber-><span class="hljs-built_in">getText</span>().<span class="hljs-built_in">c_str</span>());<br><br> ConsoleNotifier cn;<br> <br> <span class="hljs-function">FileSplitter <span class="hljs-title">splitter</span><span class="hljs-params">(filePath, number)</span></span>;<br><br> splitter.<span class="hljs-built_in">addIProgress</span>(<span class="hljs-keyword">this</span>); <span class="hljs-comment">// 订阅通知</span><br> splitter.<span class="hljs-built_in">addIProgress</span>(&cn); <span class="hljs-comment">// 订阅通知</span><br><br> splitter.<span class="hljs-built_in">split</span>();<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DoProgress</span><span class="hljs-params">(<span class="hljs-type">float</span> value)</span> </span>{<br> progressBar-><span class="hljs-built_in">setValue</span>(value);<br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ConsoleNotifier</span> : <span class="hljs-keyword">public</span> IProgress {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DoProgress</span><span class="hljs-params">(<span class="hljs-type">float</span> value)</span> </span>{<br> cout << <span class="hljs-string">"."</span>;<br> }<br>}<br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong></p><ul><li>We can change objective and observer separately with observer pattern to loosen coupling of objective and observer.</li><li>目标发送通知时,无需指定观察者,通知会自动传播。</li><li>观察者自己决定是否需要订阅通知,目标对象对此一无所知。</li></ul><h1 id="五装饰模式">五、装饰模式</h1><p><strong>Motivation:</strong> 过度使用继承来拓展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多,各种子类的组合会导致更多子类的膨胀。</p><p><strong>Definition:</strong> 动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码,减少子类个数)。</p><p><strong>Case1:</strong> <span class="math inline">\(1 + n + n * (2^m - 1)\)</span></p><p>其中<span class="math inline">\((2^m - 1) = C_m^1 + \cdots + C_m^m\)</span></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Stream</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">int</span> data)</span> </span>= <span class="hljs-number">0</span>;<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">FileStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">NetworkStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MemoryStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-comment">// 拓展操作</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CryptoFileStream</span> : <span class="hljs-keyword">public</span> FileStream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> FileStream::<span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> FileStream::<span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> FileStream::<span class="hljs-built_in">Write</span>(data);<br> }<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CryptoNetworkStream</span> : <span class="hljs-keyword">public</span> NetworkStream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> NetworkStream::<span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> NetworkStream::<span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> NetworkStream::<span class="hljs-built_in">Write</span>(data);<br> }<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CryptoMemoryStream</span> : <span class="hljs-keyword">public</span> MemoryStream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> MemoryStream::<span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> MemoryStream::<span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> MemoryStream::<span class="hljs-built_in">Write</span>(data);<br> }<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BufferedFileStream</span> : <span class="hljs-keyword">public</span> FileStream {};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BufferedNetworkStream</span> : <span class="hljs-keyword">public</span> NetworkStream {};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BufferedMemoryStream</span> : <span class="hljs-keyword">public</span> MemoryStream {};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CryptoBufferedFileStream</span> : <span class="hljs-keyword">public</span> FileSstream {<br><span class="hljs-keyword">public</span>: <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> FileStream::<span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> FileStream::<span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> FileStream::<span class="hljs-built_in">Write</span>(data);<br> }<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Process</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-comment">// 编译时装配</span><br> CryptoFileStream *fs1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">CryptoFileStream</span>();<br> BufferedFileStream *fs2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">BufferedFileStream</span>();<br> CryptoBufferedFileStream *fs3 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">CryptoBufferedFileStream</span>();<br>}<br></code></pre></td></tr></table></figure><p><strong>Case2:</strong> <span class="math inline">\(1 + n + 1 + m\)</span></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Stream</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">int</span> data)</span> </span>= <span class="hljs-number">0</span>;<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">FileStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">NetworkStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MemoryStream</span> : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(<span class="hljs-type">char</span> data)</span> </span>{}<br>}; <br><br><span class="hljs-comment">// 拓展操作</span><br><br>DecoratorStream : <span class="hljs-keyword">public</span> Stream {<br><span class="hljs-keyword">protected</span>:<br> Stream* stream;<br><br> <span class="hljs-built_in">DecoratorStream</span>(Stream * stm) : <span class="hljs-built_in">stream</span>(stm) {}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">CryptoStream</span> : <span class="hljs-keyword">public</span> DecoratorStream { <span class="hljs-comment">// 继承为了接口规范</span><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">CryptoStream</span>(Stream *stm): <span class="hljs-built_in">DecoratorStream</span>(stm) {}<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> stream-><span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> stream-><span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> stream-><span class="hljs-built_in">Write</span>(data);<br> }<br>}; <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BufferedStream</span> : <span class="hljs-keyword">public</span> DecoratorStream { <span class="hljs-comment">// 继承为了接口规范</span><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">BufferedStream</span>(Stream *stm): <span class="hljs-built_in">DecoratorStream</span>(stm) {}<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Read</span><span class="hljs-params">(<span class="hljs-type">int</span> number)</span> </span>{<br> stream-><span class="hljs-built_in">Read</span>(number);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Seek</span><span class="hljs-params">(<span class="hljs-type">int</span> position)</span> </span>{<br> stream-><span class="hljs-built_in">Seek</span>(position);<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">char</span> <span class="hljs-title">Write</span><span class="hljs-params">(byte data)</span> </span>{<br> stream-><span class="hljs-built_in">Write</span>(data);<br> }<br>}; <br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Process</span><span class="hljs-params">()</span> </span>{<br><br> <span class="hljs-comment">// 运行时装配</span><br> FileStream* s1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">FileStream</span>();<br> CryptoStream* s2 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">CryptoStream</span>(s1);<br> BufferedSteam1* s3 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">BufferedStream</span>(s1);<br> BufferedSteam1* s4 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">BufferedStream</span>(s2); <span class="hljs-comment">// CryptoBufferedStream</span><br>}<br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong> - 通过组合而非继承的方法,实现了运行时动态扩展对象功能的能力</p><h1 id="六桥模式">六、桥模式</h1><p><strong>Motivation:</strong> 由于某些类型的固有实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。</p><p><strong>Definition:</strong> 将抽象部分与实现部分分离,使他们都可以独立地变化。</p><p><strong>Case1: <span class="math inline">\(1 + n + m * n\)</span></strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Messager</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br><br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">Messager</span>(){}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PCMessagerBase</span> : <span class="hljs-keyword">public</span> Messager {<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>{};<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>{};<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MobileMessagerBase</span> : <span class="hljs-keyword">public</span> Messager {<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>{};<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>{};<br>}<br><br><span class="hljs-comment">// 业务抽象</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PCMessagerLite</span> : <span class="hljs-keyword">public</span> PCMessagerBase {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">DrawShape</span>();<br> };<br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PCMessagerPerfect</span> : <span class="hljs-keyword">public</span> PCMessagerBase {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> PCMessagerBase::<span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> PCMessagerBase::<span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> PCMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> PCMessagerBase::<span class="hljs-built_in">DrawShape</span>();<br> };<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MobileMessagerLite</span> : <span class="hljs-keyword">public</span> MobileMessagerBase {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">DrawShape</span>();<br> };<br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MobileMessagerPerfect</span> : <span class="hljs-keyword">public</span> MobileMessagerBase {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> MobileMessagerBase::<span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> MobileMessagerBase::<span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> MobileMessagerBase::<span class="hljs-built_in">PlaySound</span>();<br> MobileMessagerBase::<span class="hljs-built_in">DrawShape</span>();<br> };<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Process</span><span class="hljs-params">()</span></span>{<br> Messager *m = <span class="hljs-keyword">new</span> <span class="hljs-built_in">MobileMessagerPerfect</span>();<br>}<br></code></pre></td></tr></table></figure><p><strong>Case2: <span class="math inline">\(1 + n + 1 + m\)</span></strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Messager</span> {<br><span class="hljs-keyword">protected</span>:<br> MessagerImp* messagerImp;<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>= <span class="hljs-number">0</span>;<br><br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">Messager</span>(){}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MessagerImp</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br><br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">MessagerImp</span>(){}<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PCMessagerImp</span> : <span class="hljs-keyword">public</span> MessagerImp {<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>{};<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>{};<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MobileMessagerImp</span> : <span class="hljs-keyword">public</span> MessagerImp {<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">PlaySound</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">DrawShape</span><span class="hljs-params">()</span> </span>{}<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">WriteText</span><span class="hljs-params">()</span> </span>{};<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Connect</span><span class="hljs-params">()</span> </span>{};<br>}<br><br><span class="hljs-comment">// 业务抽象</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MessagerLite</span> : <span class="hljs-keyword">public</span> Messager {<br> <br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> messagerImp-><span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> messagerImp-><span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> messagerImp-><span class="hljs-built_in">DrawShape</span>();<br> };<br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MessagerPerfect</span> : <span class="hljs-keyword">public</span> Messager {<br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">Login</span><span class="hljs-params">(string username, string password)</span> </span>{<br> messagerImp-><span class="hljs-built_in">PlaySound</span>();<br> messagerImp-><span class="hljs-built_in">Connect</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendMessage</span><span class="hljs-params">(string message)</span> </span>{<br> messagerImp-><span class="hljs-built_in">PlaySound</span>();<br> messagerImp-><span class="hljs-built_in">WriteText</span>();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">SendPicture</span><span class="hljs-params">(Image image)</span> </span>{<br> messagerImp-><span class="hljs-built_in">PlaySound</span>();<br> messagerImp-><span class="hljs-built_in">DrawShape</span>();<br> };<br>}<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Process</span><span class="hljs-params">()</span></span>{<br> MessagerImp *mImp = <span class="hljs-keyword">new</span> <span class="hljs-built_in">PCMessagerImp</span>();<br> Messager *m = <span class="hljs-keyword">new</span> <span class="hljs-built_in">MessagerPerfect</span>(mImp);<br>}<br><br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong></p><ul><li>Bridege pattern 使用对象间的组合关系解耦合了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化.</li></ul><h1 id="七工厂方法模式">七、工厂方法模式</h1><p><strong>Motivation:</strong></p><ul><li><p>在软件系统中,经常面临着创建对象的工作,由于需求的变化,需要创建的对象的具体类型经常变化。</p></li><li><p>绕过常规的对象创建方法(new),提供一种封装机制来避免客户程序和具体对象创建工作的紧耦合。</p></li></ul><p><strong>Definition:</strong> 将抽象部分与实现部分分离,使他们都可以独立地变化。</p><p><strong>Case1:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">ISplitter</span>{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">ISplitter</span>(){}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">FileSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><span class="hljs-keyword">public</span>: <br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>{<br><br> }<br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BinarySplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TxtSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PictureSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">VideoSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MainForm</span> : <span class="hljs-keyword">public</span> Form<br>{<br><br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Button1_Click</span><span class="hljs-params">()</span> </span>{<br> string filePath = txtFilePath-><span class="hljs-built_in">getText</span>();<br> <span class="hljs-type">int</span> number = <span class="hljs-built_in">atoi</span>(txtFileNumber-><span class="hljs-built_in">getText</span>().<span class="hljs-built_in">c_str</span>());<br><br> ISplitter * splitter = <span class="hljs-keyword">new</span> <span class="hljs-built_in">FileSplitter</span>(filePath, number); <span class="hljs-comment">// 依赖具体类,这里写死了是FileSplitter,违反依赖导致原:抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。</span><br> splitter-><span class="hljs-built_in">split</span>();<br> }<br>}<br></code></pre></td></tr></table></figure><p><strong>Case2:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">SplitterFactory</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">CreateSplitter</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">SplitterFactory</span>() {}<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">ISplitter</span>{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">ISplitter</span>(){}<br>};<br><br><br><span class="hljs-comment">// 具体类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BinarySplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TxtSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PictureSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">VideoSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br><br>};<br><br><span class="hljs-comment">// 具体工厂</span><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BinarySplitterFactory</span>: <span class="hljs-keyword">public</span> SplitterFactory {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">CreateSplitter</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">BinarySplitter</span>();<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TxtSplitterFactory</span>: <span class="hljs-keyword">public</span> SplitterFactory {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">CreateSplitter</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TxtSplitter</span>();<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PictureSplitterFactory</span>: <span class="hljs-keyword">public</span> SplitterFactory {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">CreateSplitter</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">PictureSplitter</span>();<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">VedioSplitterFactory</span>: <span class="hljs-keyword">public</span> SplitterFactory {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">CreateSplitter</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">VedioSplitter</span>();<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MainForm</span> : <span class="hljs-keyword">public</span> Form<br>{<br> SplitterFactory* factory;<br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-built_in">MianForm</span>(SplitterFactory* factory) {<br> <span class="hljs-keyword">this</span>->factory = factory;<br> }<br><br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Button1_Click</span><span class="hljs-params">()</span> </span>{<br> <br> ISplitter* splitter = factory-><span class="hljs-built_in">CreateSplitter</span>(); <br> splitter-><span class="hljs-built_in">split</span>();<br> }<br>}<br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong></p><ul><li><p>Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。</p></li><li><p>Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展的策略,较好地解决了这种紧耦合关系。</p></li><li><p>Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。</p></li></ul><h1 id="八抽象工厂模式">八、抽象工厂模式</h1><p><strong>Motivation:</strong> 在软件系统中,经常面临着<strong>一系列相互依赖的对象</strong>的创建工作;同时,由于需求的变化,往往存在更多系统对象的创建工作。</p><p><strong>Definition:</strong> 提供一个接口,让改接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类。</p><p><strong>Case1:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">IBDConnection</span>{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDBConnectionFactory</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBConnection* <span class="hljs-title">CreateDBConnection</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDBCommand</span>{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDBCommandFactory</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBCommand* <span class="hljs-title">CreateDBCommand</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDataReader</span>{<br><br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDataReaderFactory</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDataReader* <span class="hljs-title">CreateIDataReader</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlConnectionFactory</span>: <span class="hljs-keyword">public</span> IDBConnectionFactory{<br><br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlConnection</span>: <span class="hljs-keyword">public</span> IDBConnection{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlCommandFactory</span>: <span class="hljs-keyword">public</span> IDBCommandFactory{<br><br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlCommand</span>: <span class="hljs-keyword">public</span> IDBCommand{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlDataReaderFactory</span>: <span class="hljs-keyword">public</span> IDataReaderFactory{<br><br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlDataReader</span>: <span class="hljs-keyword">public</span> IDataReader{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleConnection</span>: <span class="hljs-keyword">public</span> IDBConnection{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleCommand</span>: <span class="hljs-keyword">public</span> IDBCommand{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleDataReader</span>: <span class="hljs-keyword">public</span> IDataReader{<br><br>};<br><br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">EmployeeDAO</span>{<br> IDBConnectionFactory* dbConnectionFactory;<br> IDBCommandFactory* dbCommandFactory;<br> IDataReaderFactory* dataReaderFactory; <br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function">vector<EmployeeDO> <span class="hljs-title">GetEmployees</span><span class="hljs-params">()</span></span>{<br> IDBConnection* connection = IDBConnectionFactory-><span class="hljs-built_in">createDBConnection</span>();<br> connection-><span class="hljs-built_in">ConnectionString</span>(<span class="hljs-string">"..."</span>);<br><br> IDBCommand* command = IDBCommandFactory-><span class="hljs-built_in">createDBCommand</span>();<br> command-><span class="hljs-built_in">CommandText</span>(<span class="hljs-string">"..."</span>);<br> command-><span class="hljs-built_in">SetConnection</span>(connection); <span class="hljs-comment">// 关联性</span><br><br> IDBDataReader* reader = command-><span class="hljs-built_in">ExecuteReader</span>(); <span class="hljs-comment">// 关联性</span><br> <span class="hljs-keyword">while</span> (reader-><span class="hljs-built_in">Read</span>()) {<br> <br> }<br> }<br>}<br><br></code></pre></td></tr></table></figure><p><strong>case2:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IBDConnection</span>{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDBCommand</span>{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDataReader</span>{<br><br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">IDBFactory</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBConnection* <span class="hljs-title">CreateDBConnection</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBCommand* <span class="hljs-title">CreateDBCommand</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDataReader* <span class="hljs-title">CreateIDataReader</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br>}<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlDBFactory</span>: <span class="hljs-keyword">public</span> IDBFactory{<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBConnection* <span class="hljs-title">CreateDBConnection</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDBCommand* <span class="hljs-title">CreateDBCommand</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> IDataReader* <span class="hljs-title">CreateIDataReader</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br>} <br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlConnection</span>: <span class="hljs-keyword">public</span> IDBConnection{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlCommand</span>: <span class="hljs-keyword">public</span> IDBCommand{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">SqlDataReader</span>: <span class="hljs-keyword">public</span> IDataReader{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleConnection</span>: <span class="hljs-keyword">public</span> IDBConnection{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleCommand</span>: <span class="hljs-keyword">public</span> IDBCommand{<br><br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">OracleDataReader</span>: <span class="hljs-keyword">public</span> IDataReader{<br><br>};<br><br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">EmployeeDAO</span>{<br> IDBFactory* dbFactory;<br> <br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function">vector<EmployeeDO> <span class="hljs-title">GetEmployees</span><span class="hljs-params">()</span></span>{<br> IDBConnection* connection = dbFactory-><span class="hljs-built_in">createDBConnection</span>();<br> connection-><span class="hljs-built_in">ConnectionString</span>(<span class="hljs-string">"..."</span>);<br><br> IDBCommand* command = dbFactory-><span class="hljs-built_in">createDBCommand</span>();<br> command-><span class="hljs-built_in">CommandText</span>(<span class="hljs-string">"..."</span>);<br> command-><span class="hljs-built_in">SetConnection</span>(connection); <span class="hljs-comment">// 关联性</span><br><br> IDBDataReader* reader = command-><span class="hljs-built_in">ExecuteReader</span>(); <span class="hljs-comment">// 关联性</span><br> <span class="hljs-keyword">while</span> (reader-><span class="hljs-built_in">Read</span>()) {<br> <br> }<br> }<br>}<br><br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong> - 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。</p><ul><li><p>“系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列对象之间不能相互依赖。</p></li><li><p>Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。</p></li></ul><h1 id="原型模式">原型模式</h1><p><strong>Motivation:</strong> 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。</p><p><strong>Definition:</strong> 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。</p><p><strong>case 2:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">ISplitter</span> {<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">clone</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>; <br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> <span class="hljs-type">void</span> <span class="hljs-title">split</span><span class="hljs-params">()</span> </span>= <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">virtual</span> ~<span class="hljs-built_in">ISplitter</span>(){}<br>};<br><br><br><span class="hljs-comment">// 具体类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BinarySplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">clone</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">BinarySplitter</span>(*<span class="hljs-keyword">this</span>);<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">TxtSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">clone</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">TxtSplitter</span>(*<span class="hljs-keyword">this</span>);<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">PictureSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">clone</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">PictureSplitter</span>(*<span class="hljs-keyword">this</span>);<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">VideoSplitter</span> : <span class="hljs-keyword">public</span> ISplitter{<br> <span class="hljs-function"><span class="hljs-keyword">virtual</span> ISplitter* <span class="hljs-title">clone</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">VideoSplitter</span>(*<span class="hljs-keyword">this</span>);<br> }<br>};<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MainForm</span> : <span class="hljs-keyword">public</span> Form<br>{<br> ISplitter* prototype; <span class="hljs-comment">// 原型对象</span><br><span class="hljs-keyword">public</span>:<br><br> <span class="hljs-built_in">MianForm</span>(ISplitter* prototype) {<br> <span class="hljs-keyword">this</span>->prototype = prototype;<br> }<br><br> <span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Button1_Click</span><span class="hljs-params">()</span> </span>{<br> <br> ISplitter* splitter = prototype-><span class="hljs-built_in">clone</span>(); <span class="hljs-comment">// 克隆原型 </span><br> splitter-><span class="hljs-built_in">split</span>();<br> }<br>}<br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong> - 什么时候用原型什么时候用工厂?用工厂模式创建对象是否是几个简单的步骤就能创建出来,还是说要考虑对象复杂的中间状态。 - 原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些“易变类”拥有“稳定的接口”。 - 原型模式对于“如何创建易变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象--所需工作仅仅是注册一个新类的对象(即原型),然后再任何需要的地方Clone。 - 原型模式中的Clone方法可以利用某些框架中的序列化来实现深拷贝。</p><h1 id="构建器">构建器</h1><p><strong>Motivation:</strong> 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。</p><h1 id="单例模式">单例模式</h1><p><strong>Motivation:</strong></p><ul><li><p>在软件系统中,经常有一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。</p></li><li><p>如何绕过常规的构造器,提供一种机制保证一个类只有一个实例</p></li></ul><p><strong>Definition:</strong> 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。</p><p><strong>Case1:</strong></p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Singleton</span> {<br><span class="hljs-keyword">private</span>:<br> <span class="hljs-built_in">Singleton</span>();<br> <span class="hljs-built_in">Singleton</span>(<span class="hljs-type">const</span> Singlton& other);<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-function"><span class="hljs-type">static</span> Singleton* <span class="hljs-title">getInstance</span><span class="hljs-params">()</span></span>;<br> <span class="hljs-type">static</span> Singleton* m_instance; <br>}<br><br>Singleton* Singleton::m_instance = <span class="hljs-literal">nullptr</span>;<br><br><span class="hljs-comment">// MT non-safe</span><br><span class="hljs-function">Sington* <span class="hljs-title">Singleton::getInstance</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">if</span> (!m_instance) m_instance = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Singleton</span>();<br> <span class="hljs-keyword">return</span> m_instnace;<br>}<br><br><span class="hljs-comment">// MT safe</span><br><span class="hljs-function">Sington* <span class="hljs-title">Singleton::getInstance</span><span class="hljs-params">()</span> </span>{<br> Lock lock;<br> <span class="hljs-keyword">if</span> (!m_instance) m_instance = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Singleton</span>();<br> <span class="hljs-keyword">return</span> m_instnace;<br>}<br><br><span class="hljs-comment">// double-check lock while reordering non-safe</span><br><span class="hljs-function">Sington* <span class="hljs-title">Singleton::getInstance</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">if</span> (!m_instance) {<br> Lock lock;<br> <span class="hljs-keyword">if</span> (!m_instance) m_instance = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Singleton</span>();<br> }<br> <span class="hljs-keyword">return</span> m_instnace;<br>}<br><br><span class="hljs-comment">// C++ 11 volatile</span><br><br>std::atomic<Singleton*> Singleton::m_instance;<br>std::mutex Singtle::m_mutex;<br><br><span class="hljs-function">Singleton* <span class="hljs-title">Singleton::getInstance</span><span class="hljs-params">()</span> </span>{<br> Singleton* tmp = m_instance.<span class="hljs-built_in">load</span>(std::memory_order_relaxed);<br> std::<span class="hljs-built_in">atomic_thread_fence</span>(std::memory_order_acquire); <span class="hljs-comment">// acquire fence</span><br> <span class="hljs-keyword">if</span> (tmp == nulpptr) {<br> <span class="hljs-function">std::lock_guard<std::mutex> <span class="hljs-title">lock</span><span class="hljs-params">(m_mutex)</span></span>;<br> tmp = m_instance.<span class="hljs-built_in">load</span>(std::memory_oder_relaxed);<br> <span class="hljs-keyword">if</span> (tmp == <span class="hljs-literal">nullptr</span>) {<br> tmp = <span class="hljs-keyword">new</span> Singleton;<br> std::<span class="hljs-built_in">atomic_thread_fence</span>(std::memory_order_release); <span class="hljs-comment">// release fence</span><br> m_instance.<span class="hljs-built_in">store</span>(tmp, std::memory_order_relaxed);<br> }<br> }<br>}<br><br></code></pre></td></tr></table></figure><p><strong>Conclusion:</strong></p><ul><li><p>Singleton模式中的实例构造器可以设置为protected</p></li><li><p>Singleton模式一般不要支持拷贝构造函数,因为有可能导致多个对象实例</p></li><li><p>多线程下安全的Singleton</p></li></ul>]]></content>
<categories>
<category>Programming</category>
<category>Python</category>
</categories>
</entry>
<entry>
<title>My Vim Cheat Sheet</title>
<link href="/Programming/Python/Vim%20Cheat%20Sheet/"/>
<url>/Programming/Python/Vim%20Cheat%20Sheet/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="cursor-movement">Cursor movement</h1><p><strong>i:</strong> move cursor up</p><p><strong>k:</strong> move cursor down</p><p><strong>j:</strong> move cursor left</p><p><strong>l:</strong> move cursor right</p><p><strong>I:</strong> move cursor up 5 lines</p><p><strong>K:</strong> move cursor down 5 lines</p><p><strong>J:</strong> move cursor left 5 characters</p><p><strong>L:</strong> move cursor right 5 characters</p>]]></content>
<categories>
<category>Programming</category>
<category>Python</category>
</categories>
</entry>
<entry>
<title>VSCode Configuration</title>
<link href="/Programming/Python/VSCode%20Configuration/"/>
<url>/Programming/Python/VSCode%20Configuration/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><!-- TOC --><ul><li><a href="#hotkey">Hotkey</a><ul><li><a href="#general">General</a></li><li><a href="#basic-editing">Basic editing</a></li><li><a href="#navigation">Navigation</a></li><li><a href="#editor-management">Editor management</a></li><li><a href="#rich-languages-editing">Rich languages editing</a></li><li><a href="#file-management">File management</a></li><li><a href="#display">Display</a></li><li><a href="#debug">Debug</a></li><li><a href="#integrated-terminal">Integrated terminal</a></li><li><a href="#bookmark">BookMark</a></li></ul></li><li><a href="#cc">C/C++</a></li><li><a href="#vim">Vim</a></li></ul><!-- /TOC --><!-- /TOC --><!-- /TOC --><h1 id="hotkey">Hotkey</h1><h2 id="general">General</h2><table><tbody><tr class="odd"><td>Ctrl+Shift+P</td><td>Show command palette</td></tr><tr class="even"><td>Ctrl+P</td><td>Quick Open</td></tr><tr class="odd"><td>Ctrl+Shift+N</td><td>New window</td></tr><tr class="even"><td>Ctrl+Shift+W</td><td>Close window</td></tr></tbody></table><h2 id="basic-editing">Basic editing</h2><table><tbody><tr class="odd"><td>Ctrl+Shift+[</td><td>Fold region</td></tr><tr class="even"><td>Ctrl+Shift+]</td><td>Unfold region</td></tr><tr class="odd"><td>Ctrl+K+Ctrl+[</td><td>Fold all subregions</td></tr><tr class="even"><td>Ctrl+K+Ctrl+]</td><td>Unfold all subregions</td></tr></tbody></table><h2 id="navigation">Navigation</h2><table><tbody><tr class="odd"><td>Alt+<span class="math inline">\(\leftarrow\)</span></td><td>Navigate back</td></tr><tr class="even"><td>Alt+<span class="math inline">\(\rightarrow\)</span></td><td>Navigate forward</td></tr></tbody></table><h2 id="editor-management">Editor management</h2><table><tbody><tr class="odd"><td>Ctrl+W</td><td>Close editor</td></tr><tr class="even"><td>Ctrl+\</td><td>Split editor</td></tr><tr class="odd"><td>Ctrl+1/2/3</td><td>Focus into 1st, 2nd or 3rd editor group</td></tr><tr class="even"><td>Ctrl+K+Ctrl+<span class="math inline">\(\leftarrow\)</span> / <span class="math inline">\(\rightarrow\)</span></td><td>Focus into left/right editor group</td></tr><tr class="odd"><td>Ctrl+Alt+Z</td><td>Focus into next editor group</td></tr><tr class="even"><td>Ctrl+Shift+PgUp/PgDown</td><td>Move editor left/right</td></tr><tr class="odd"><td>Ctrl+K+<span class="math inline">\(\leftarrow\)</span> / <span class="math inline">\(\rightarrow\)</span></td><td>Move active editor group</td></tr><tr class="even"><td>Ctrl+Alt+<span class="math inline">\(\rightarrow\)</span></td><td>Move to next editor group</td></tr><tr class="odd"><td>Ctrl+Alt+<span class="math inline">\(\leftarrow\)</span></td><td>Move to previous editor group</td></tr></tbody></table><h2 id="rich-languages-editing">Rich languages editing</h2><table><tbody><tr class="odd"><td>Shift+Alt+F</td><td>Format document</td></tr></tbody></table><h2 id="file-management">File management</h2><table><tbody><tr class="odd"><td>Ctrl+Tab</td><td>Open next</td></tr><tr class="even"><td>Ctrl+Shift+Tab</td><td>Open previous</td></tr><tr class="odd"><td>Ctrl+K+P</td><td>Copy path of active file</td></tr><tr class="even"><td>Ctrl+N</td><td>New file</td></tr><tr class="odd"><td>Ctrl+O</td><td>Open file</td></tr><tr class="even"><td>Shift+Alt+C</td><td>Copy path of active file</td></tr></tbody></table><h2 id="display">Display</h2><table><tbody><tr class="odd"><td>Ctrl+Shift+Q</td><td>Show Explorer</td></tr><tr class="even"><td>Ctrl+Shift+F</td><td>Show Search</td></tr><tr class="odd"><td>Ctrl+Shift+G G</td><td>Show Git</td></tr><tr class="even"><td>Ctrl+Shift+D</td><td>Show Debug</td></tr><tr class="odd"><td>Ctrl+K+V</td><td>Open Markdown preview to the side</td></tr><tr class="even"><td>Ctrl+Alt+X</td><td>Show Outline</td></tr></tbody></table><h2 id="debug">Debug</h2><table><tbody><tr class="odd"><td>F9</td><td>Toggle breakpoint</td></tr><tr class="even"><td>F5</td><td>Continue</td></tr><tr class="odd"><td>Shift+F5</td><td>Stop</td></tr><tr class="even"><td>F11/Shift F11</td><td>Step into/out</td></tr><tr class="odd"><td>F10</td><td>Step over</td></tr></tbody></table><h2 id="integrated-terminal">Integrated terminal</h2><table><tbody><tr class="odd"><td>Ctrl+`</td><td>Show integrated terminal</td></tr><tr class="even"><td>Ctrl+Shift+`</td><td>Create new terminal</td></tr><tr class="odd"><td>Ctrl+Shift+C</td><td>Copy selection</td></tr><tr class="even"><td>Ctrl+Shift+V</td><td>Paste into active terminal</td></tr><tr class="odd"><td>Ctrl+PgUp/PgDown</td><td>Focus on previous/next terminal group</td></tr><tr class="even"><td>Alt+Delete</td><td>Kill the active terminal instance</td></tr></tbody></table><h2 id="bookmark">BookMark</h2><table><tbody><tr class="odd"><td>Ctrl+ALT+K</td><td>Toggle</td></tr><tr class="even"><td>Ctrl+K Ctrl+ALT+K</td><td>Focus</td></tr></tbody></table><h1 id="cc">C/C++</h1><h1 id="vim">Vim</h1>]]></content>
<categories>
<category>Programming</category>
<category>Python</category>
</categories>
</entry>
<entry>
<title>Boost</title>
<link href="/Programming/C-C/C++%20Cookbook/Boost/"/>
<url>/Programming/C-C/C++%20Cookbook/Boost/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h2 id="boostsplit">boost::split</h2><p>#include <boost/algorithm/string.hpp></p><p><strong>Description:</strong> boost::split()函数用于切割string字符串,将切割之后的字符串放到一个std::vector<std::string> 之中。</p><p>有4个参数:</p><p>boost::split(type, select_list, boost::is_any_of(","), boost::token_compress_on);</p><p>(1)、type类型是std::vector<std::string>,用于存放切割之后的字符串</p><p>(2)、select_list:传入的字符串,可以为空。</p><p>(3)、boost::is_any_of(","):设定切割符为,(逗号)</p><p>(4)、 boost::token_compress_on:将连续多个分隔符当一个,默认没有打开,当用的时候一般是要打开的。</p>]]></content>
<categories>
<category>Programming</category>
<category>C/C++</category>
</categories>
</entry>
<entry>
<title>强化学习中的off-line, on-line, off policy, on policy傻傻分不清</title>
<link href="/Artificial-Intelligence/RL/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0%E4%B8%AD%E7%9A%84off-line,%20on-line,%20off%20policy,%20on%20policy%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85/"/>
<url>/Artificial-Intelligence/RL/%E5%BC%BA%E5%8C%96%E5%AD%A6%E4%B9%A0%E4%B8%AD%E7%9A%84off-line,%20on-line,%20off%20policy,%20on%20policy%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://blog.csdn.net/qq_42743778/article/details/120063861">https://blog.csdn.net/qq_42743778/article/details/120063861</a></p><p><a href="https://zhuanlan.zhihu.com/p/346433931">https://zhuanlan.zhihu.com/p/346433931</a></p>]]></content>
<categories>
<category>Artificial Intelligence</category>
<category>RL</category>
</categories>
</entry>
<entry>
<title>Leetcode</title>
<link href="/Programming/Leetcode/Leetcode/"/>
<url>/Programming/Leetcode/Leetcode/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="字符串">字符串</h1><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1657/">1657.确定两个字符串是否接近</a></p><h1 id="others">Others</h1><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1/">1.两数之和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:2.两数相加/">2.两数相加</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode3/">3.无重复字符的最长子串</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:4.寻找两个有序数组的中位数/">4.寻找两个有序数组的中位数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:5.最长回文子串/">5.最长回文子串</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:7.整数反转/">7.整数反转</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:8.字符串转换整数/">8.字符串转换整数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:9.回文数/">9.回文数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode10/">10.正则表达式匹配</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:11.盛最多水的容器/">11.盛最多水的容器</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode13/">13. 罗马数字转整数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:14.最长公共前缀/">14.最长公共前缀</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:15.三数之和/">15.三数之和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:16.最接近的三数之和/">16.最接近的三数之和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode17/">17. 电话号码的字母组合</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode19/">19. 删除链表的倒数第 N 个结点</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:20.有效的括号/">20.有效的括号</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:21.合并两个有序链表/">21.合并两个有序链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode22/">22. 括号生成</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:23.合并K个排序链表/">23.合并K个排序链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode24/">24. 两两交换链表中的节点</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode25/">25. K 个一组翻转链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:26.删除排序数组中重复的项/">26.删除排序数组中重复的项</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode27/">27. 移除元素</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:33.搜索旋转排序数组/">33.搜索旋转排序数组</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:43.字符串相乘/">43.字符串相乘</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode44/">44. 通配符匹配</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:46.全排列/">46.全排列</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:53.最大子序和/">53.最大子序和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:54.螺旋矩阵/">54.螺旋矩阵</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode55/">55. 跳跃游戏</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:59.螺旋矩阵二/">59.螺旋矩阵二</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:61.旋转链表/">61.旋转链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:62.不同路径/">62.不同路径</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:70.爬楼梯/">70.爬楼梯</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:78.子集/">78.子集</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode82/">82. 删除排序链表中的重复元素 II</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:88.合并两个有序数组/">88.合并两个有序数组</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:89.格雷编码/">89.格雷编码</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode94/">94. 二叉树的中序遍历</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode95/">95. 不同的二叉搜索树 II</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode99/">99. 恢复二叉搜索树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode100/">100.相同的树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode101/">101. 对称二叉树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:104.二叉树最大深度/">104.二叉树最大深度</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode105/">105. 从前序与中序遍历序列构造二叉树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode106/">106. 从中序与后序遍历序列构造二叉树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode108/">108. 将有序数组转换为二叉搜索树</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:121.买卖股票的最佳时机/">121.买卖股票的最佳时机</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:122.买卖股票的最佳时机II/">122.买卖股票的最佳时机II</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:124.二叉树最大路径和/">124.二叉树最大路径和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode134/">134. 加油站</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:136.只出现一次的数字/">136.只出现一次的数字</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:141.环形链表/">141.环形链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:142.环形链表II/">142.环形链表II</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:146.LRU缓存机制/">146.LRU缓存机制</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:148.排序链表/">148.排序链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:155.最小栈/">155.最小栈</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:160.相交链表/">160.相交链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:169.众数/">169.众数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode203/">203. 移除链表元素</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:206.反转链表/">206.反转链表</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode208/">208. 实现 Trie (前缀树)</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:215.数组中的第K个最大元素/">215.数组中的第K个最大元素</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:217.存在重复元素/">217.存在重复元素</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:230.二叉搜索树中第K小的元素/">230.二叉搜索树中第K小的元素</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:231.2的幂/">231.2的幂</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:235.二叉搜索树的最近公共祖先/">235.二叉搜索树的最近公共祖先</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:236.二叉树的最近公共祖先/">236.二叉树的最近公共祖先</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:237.%20删除链表中的节点/">237. 删除链表中的节点</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:238.%20除自身以外数组的乘积/">238. 除自身以外数组的乘积</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:292.%20Nim%20游戏/">292. Nim 游戏</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode322/">322. 零钱兑换</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:344.%20反转字符串/">344. 反转字符串</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode392/">392. 判断子序列</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode415/">415. 字符串相加</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode435/">435. 无重叠区间</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode455/">455. 分发饼干</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode516/">516. 最长回文子序列</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode实战:557.%20反转字符串中的单词%20III/">557. 反转字符串中的单词 III</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode907/">907. 子数组的最小值之和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1012/">1012. 至少有 1 位重复的数字</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1143/">1143. 最长公共子序列</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1260/">1260. 二维网格迁移</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1487/">1487. 保证文件名唯一</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1605/">1605. 给定行和列的和求可行矩阵</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1615/">1615. 最大网络秩</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1626/">1626. 无矛盾的最佳球队</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1653/">1653. 使字符串平衡的最少删除次数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1721/">1721. 交换链表中的节点</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1775/">1775. 通过最少操作次数使数组的和相等</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1780/">1780. 判断一个数字是否可以表示成三的幂的和</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode1812/">1812. 判断国际象棋棋盘中一个格子的颜色</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2363/">2363. 合并相似的物品</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2373/">2373. 矩阵中的局部最大值</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2379/">2379. 得到 K 个黑块的最少涂色次数</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2383/">2383. 赢得比赛需要的最少训练时长</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2389/">2389. 和有限的最长子序列</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2469/">2469. 温度转换</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/Leetcode2488/">2488. 统计中位数为 K 的子数组</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/offer16/">剑指 Offer 16. 数值的整数次方</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/offer47/">剑指 Offer 47. 礼物的最大价值</a></p><p><a href="https://chenxindaaa.com/Programming/Leetcode/Leetcode/面试题05.02/">面试题 05.02. 二进制数转字符串</a></p>]]></content>
<categories>
<category>Programming</category>
<category>Leetcode</category>
</categories>
</entry>
<entry>
<title>Docker</title>
<link href="/Programming/Docker/Docker/"/>
<url>/Programming/Docker/Docker/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="docker教程">Docker教程</h1><h2 id="一docker三要素">一、Docker三要素:</h2><ol type="1"><li>image <span class="math inline">\(\rightarrow\)</span> class</li><li>container <span class="math inline">\(\rightarrow\)</span> instance</li><li>repository <span class="math inline">\(\rightarrow\)</span> 存放image的场所,官方registry称为Docker Hub</li></ol><h2 id="二安装">二、安装</h2><p><a href="https://docs.docker.com/engine/">步骤</a></p><p><code>Note:Set up the repository</code></p><p><a href="https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors">阿里云镜像加速</a></p><h2 id="三docker常用命令">三、Docker常用命令</h2><h3 id="帮助启动类命令">3.1 帮助启动类命令</h3><figure class="highlight nsis"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs nsis"><span class="hljs-params">system</span>ctl start docker <span class="hljs-comment"># 启动docker</span><br><span class="hljs-params">system</span>ctl stop docker <span class="hljs-comment"># 停止docker</span><br><span class="hljs-params">system</span>ctl restart docker <span class="hljs-comment"># 重启docker</span><br><span class="hljs-params">system</span>ctl status docker <span class="hljs-comment"># 查看docker状态</span><br><span class="hljs-params">system</span>ctl enable docker <span class="hljs-comment"># 开机启动</span><br>docker info <span class="hljs-comment"># 查看docker概要信息</span><br>docker --help <span class="hljs-comment"># 查看docker总体帮助文档</span><br>docker 具体命令 --help <span class="hljs-comment"># 查看docker命令帮助文档</span><br></code></pre></td></tr></table></figure><h3 id="镜像命令">3.2 镜像命令</h3><ul><li>docker images [OPTIONS]:列出本地主机上的镜像<ul><li>各个选项说明: REPOSITORY:表示镜像的仓库源 TAG:镜像的标签版本号 IMAGE ID:镜像ID CREATED:镜像创建时间 SIZE:镜像大小 同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像</li><li>OPTIONS说明:<ul><li>-a :列出本地所有的镜像(含历史映像层)</li><li>-q :只显示镜像ID。</li></ul></li></ul></li><li>docker search [OPTIONS] 镜像名字:搜索镜像<ul><li>OPTIONS说明:<ul><li>--limit : 只列出N个镜像,默认25个 e.g. docker search --limit 5 redis</li></ul></li></ul></li><li>docker pull 某个XXX镜像名字:下载镜像<ul><li>docker pull 镜像名字:[TAG] 没有TAG就是最新版等价于docker pull 镜像名字:latest</li></ul></li><li>docker system df:查看镜像/容器/数据卷所占的空间</li><li>docker rmi 某个XXX镜像名字ID:删除镜像<ul><li>删除单个 docker rmi -f 镜像ID</li><li>删除多个 docker rmi -f 镜像名1:TAG 镜像名2:TAG</li><li>删除全部 docker rmi -f $(docker images -qa) ### 3.3 容器命令</li></ul></li><li>docker run [OPTIONS] IMAGE [COMMAND] [ARG...]:新建+启动容器<ul><li>OPTIONS说明:有些是一个减号,有些是两个减号<ul><li>--name="容器新名字" 为容器指定一个名称;</li><li>-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);</li><li>启动交互式容器(前台有伪终端,等待交互)<ul><li>-i:以交互模式运行容器,通常与 -t 同时使用;(interactive)</li><li>-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;(terminal)</li><li>e.g. docker run -it ubuntu /bin/bash: 使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令 /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。要退出终端,直接输入 exit:</li></ul></li><li>-P: 随机端口映射,大写P</li><li>-p: 指定端口映射,小写p</li></ul></li></ul></li><li>docker ps [OPTIONS]:·列出当前所有正在运行的容器<ul><li>OPTIONS说明<ul><li>-a:列出当前所有正在运行的容器+历史上运行过的</li><li>-l:显示最近创建的容器。</li><li>-n:显示最近n个创建的容器。</li><li>-q:静默模式,只显示容器编号。</li></ul></li></ul></li><li>退出容器 关系 指向 进入正在运行的容器并以命令行交互 ·两种退出方式 ·exit ·run进去容器,exit退出,容器停止 ·ctrl+p+q ·run进去容器,ctrl+p+q退出,容器不停止 ·启动已停止运行的容器 ·docker start 容器ID或者容器名</li><li>重启容器 ·docker restart 容器ID或者容器名 ·停止容器 ·docker stop 容器ID或者容器名 ·强制停止容器 ·docker kill 容器ID或容器名 ·删除已停止的容器 ·docker rm 容器ID ·一次性删除多个容器实例 ·docker rm -f $(docker ps -a -q) ·docker ps -a -q | xargs docker rm</li></ul><h2 id="reference">Reference:</h2><blockquote><p><a href="https://www.bilibili.com/video/BV1gr4y1U7CY?p=1&vd_source=bd05c11d5f9bf6d6b4849b57473d2194">尚硅谷Docker实战教程</a> <a href="https://space.bilibili.com/393424102">JJacobb</a></p></blockquote>]]></content>
<categories>
<category>Programming</category>
<category>Docker</category>
</categories>
</entry>
<entry>
<title>CMake</title>
<link href="/Programming/C-C/CMake/CMake/"/>
<url>/Programming/C-C/CMake/CMake/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><h1 id="最小配置示例">最小配置示例</h1><h2 id="cmakelists.txt">CMakelists.txt</h2><figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">cmake<span class="hljs-constructor">_minimum_required(VERSION 3.0)</span> # cmake最低版本<br>project(sample CXX) # 项目名称<br>add<span class="hljs-constructor">_library(<span class="hljs-params">sample</span> <span class="hljs-params">sample</span>.<span class="hljs-params">cpp</span>)</span> # 添加库<br>add<span class="hljs-constructor">_executable(<span class="hljs-params">sample_exe</span> <span class="hljs-params">sample_exe</span>.<span class="hljs-params">cpp</span>)</span> # 添加可执行程序<br></code></pre></td></tr></table></figure><h2 id="相关函数">相关函数</h2><ul><li>project:定义工程名称,并可指定工程支持的语言<ul><li>project(projectname [CXX] [C] [Java][C CXX])</li><li>项目对应的变量:<ul><li>PROJECT_NAME:项目名称</li><li>PROJECT_SOURCE_DIR:项目源码根目录</li><li>PROJECT_VERSION:项目版本</li><li>PROJECT_BINARY_DIR:项目生成的临时二进制目录,用于存放配置/编译中间文件。</li></ul></li></ul></li><li>add_library:生成库文件<ul><li>add_library(libname [SHARED|STATIC|MODULE][EXCLUDE_FROM_ALL] source)<ul><li>libname: 库名称</li><li>source:源文件,可以使用列表变量,也可以直接添加源文件名称,还可以使用函数 target_source 添加源文件</li><li>SHARED:声明该库仅被作为动态库生成</li><li>STATIC 声明该库仅被作为静态库生成</li></ul></li></ul></li><li>add_executable:生成可执行文件<ul><li>add_executable(exename source)</li></ul></li></ul><h2 id="生成项目">生成项目</h2><figure class="highlight erlang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs erlang">cmake -G <span class="hljs-string">"Unix Makefiles"</span> ..<br>make<br></code></pre></td></tr></table></figure><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs awk">cmake.exe -S .<span class="hljs-regexp">/sample -B ./</span>sample/binary -G <span class="hljs-string">"Visual Studio 16 2019"</span> -A x64<br>cmake.exe --build .<span class="hljs-regexp">/sample/</span>binary<br></code></pre></td></tr></table></figure><h3 id="命令行参数">命令行参数</h3><ul><li>-S 顶级CMakeLists.txt(包含project声明)所在路径。</li><li>-B 存放临时编译的二进制文件(.obj、.ilk等)和编译器对应的配置文件路径。</li><li>-G 编译器名称</li><li>-A 架构名称</li><li>-D 使用该变量以向cmake传入各种参数,包括选项及覆盖cmake提供的各种默认变量值。</li><li>--toolchain cmake toolchain文件路径。</li><li>--install-prefix 安装的二进制存放路径。</li><li>--trace / --trace-expand 调试时使用,用于打印已执行的cmake代码及行号。否则仅输出函数message中的内容。</li><li>--build 使用cmake直接调用编译器编译项目。</li><li>--config 选择需要编译的项目配置类型。</li><li>--install 安装已编译好的二进制文件至 CMAKE_INSTALL_PREFIX 中。</li></ul><h1 id="依赖管理">依赖管理</h1><h2 id="查找依赖">查找依赖</h2><ul><li><p><a href="https://link.zhihu.com/?target=https://cmake.org/cmake/help/latest/command/find_package.html#id7">find_package</a>:使用预先设置的配置文件来查找依赖项 <figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs inform7">find_package(PACKAGE_NAME_CASE_SENSITIVE<br> <span class="hljs-comment">[version]</span> <span class="hljs-comment">[EXACT]</span> <span class="hljs-comment">[QUIET]</span><br> <span class="hljs-comment">[REQUIRED]</span> <span class="hljs-comment">[<span class="hljs-comment">[COMPONENTS]</span> <span class="hljs-comment">[components...]</span>]</span><br> <span class="hljs-comment">[OPTIONAL_COMPONENTS components...]</span><br> <span class="hljs-comment">[CONFIG|NO_MODULE]</span><br> <span class="hljs-comment">[NO_POLICY_SCOPE]</span><br> <span class="hljs-comment">[NAMES name1 <span class="hljs-comment">[name2 ...]</span>]</span><br> <span class="hljs-comment">[CONFIGS config1 <span class="hljs-comment">[config2 ...]</span>]</span><br> <span class="hljs-comment">[HINTS path1 <span class="hljs-comment">[path2 ... ]</span>]</span><br> <span class="hljs-comment">[PATHS path1 <span class="hljs-comment">[path2 ... ]</span>]</span><br> <span class="hljs-comment">[PATH_SUFFIXES suffix1 <span class="hljs-comment">[suffix2 ...]</span>]</span><br> <span class="hljs-comment">[NO_DEFAULT_PATH]</span><br> <span class="hljs-comment">[NO_PACKAGE_ROOT_PATH]</span><br> <span class="hljs-comment">[NO_CMAKE_PATH]</span><br> <span class="hljs-comment">[NO_CMAKE_ENVIRONMENT_PATH]</span><br> <span class="hljs-comment">[NO_SYSTEM_ENVIRONMENT_PATH]</span><br> <span class="hljs-comment">[NO_CMAKE_PACKAGE_REGISTRY]</span><br> <span class="hljs-comment">[NO_CMAKE_BUILDS_PATH]</span> # Deprecated; does nothing.<br> <span class="hljs-comment">[NO_CMAKE_SYSTEM_PATH]</span><br> <span class="hljs-comment">[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]</span><br> <span class="hljs-comment">[CMAKE_FIND_ROOT_PATH_BOTH |</span><br><span class="hljs-comment"> ONLY_CMAKE_FIND_ROOT_PATH |</span><br><span class="hljs-comment"> NO_CMAKE_FIND_ROOT_PATH)</span><br></code></pre></td></tr></table></figure></p><p>常用参数:</p><ul><li>PACKAGE_NAME_CASE_SENSITIVE 查找的库的名称,大小写敏感,与之对应的是调用了包含此名称的配置文件。</li><li>version 依赖的版本号。如果依赖的配置同时提供了版本文件,则会使用该值对比配置中的版本而确定是否可以使用。</li><li>EXACT 版本号必须严格对应配置中的版本号。</li><li>QUIET 关闭了查找信息(不包含查找失败/错误信息)的输出。</li><li>REQUIRED 如果库没找到就报错。</li><li>CONFIG 该关键字声明了需要使用 依赖项通过自己的cmake代码 使用cmake 自动生成的 配置文件,入口配置文件名称一般为 <LOW_CASE_PACKAGE_NAME>-config.cmake 或 <ALL_CASE_PACKAGE_NAME>Config.cmake 。</li></ul></li><li><p>find_library:原始的cmake查找依赖方式,直接查找依赖项库文件。 <figure class="highlight prolog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs prolog">find_library (<br> <<span class="hljs-symbol">LIBRARY_NAME</span>><br> name | <span class="hljs-symbol">NAMES</span> name1 [name2 ...] [<span class="hljs-symbol">NAMES_PER_DIR</span>]<br> [<span class="hljs-symbol">HINTS</span> [path | <span class="hljs-symbol">ENV</span> var]... ]<br> [<span class="hljs-symbol">PATHS</span> [path | <span class="hljs-symbol">ENV</span> var]... ]<br> [<span class="hljs-symbol">PATH_SUFFIXES</span> suffix1 [suffix2 ...]]<br> [<span class="hljs-symbol">DOC</span> <span class="hljs-string">"cache documentation string"</span>]<br> [<span class="hljs-symbol">NO_CACHE</span>]<br> [<span class="hljs-symbol">REQUIRED</span>]<br> [<span class="hljs-symbol">NO_DEFAULT_PATH</span>]<br> [<span class="hljs-symbol">NO_PACKAGE_ROOT_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_ENVIRONMENT_PATH</span>]<br> [<span class="hljs-symbol">NO_SYSTEM_ENVIRONMENT_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_SYSTEM_PATH</span>]<br> [<span class="hljs-symbol">CMAKE_FIND_ROOT_PATH_BOTH</span> |<br> <span class="hljs-symbol">ONLY_CMAKE_FIND_ROOT_PATH</span> |<br> <span class="hljs-symbol">NO_CMAKE_FIND_ROOT_PATH</span>]<br> )<br></code></pre></td></tr></table></figure></p><ul><li>LIBRARY_NAME:由于直接查找库文件而不是查找配置文件,此名称仅作为结果中宏的前缀使用。</li><li>NAMES:此项声明了库文件的名称。值得注意的是,在UNIX-style系统中,自动添加“lib”作为库名称的前缀。</li><li>NAMES_PER_DIR:一个名称遍历查找一次,再用另一个名称遍历查找一次。而不是根据路径使用多个名称遍历。</li><li>查找完成后:<ul><li>如果查找到,则会设置 LIBRARY_NAME 为查找到的库文件的名称(包含全路径)。</li><li>如果没有查找到,则会将 LIBRARY_NAME 设置为 <LIBRARY_NAME>-NOTFOUND 。</li></ul><p>所以这里和 find_package 又有不同,我们应当使用以下代码判断是否查找到:</p><p><figure class="highlight isbl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs isbl"><span class="hljs-variable"><span class="hljs-keyword">if</span></span> (<span class="hljs-variable">PACKAGE_NAME</span> <span class="hljs-variable">MATCHES</span> <span class="hljs-string">"-NOTFOUND"</span>)<br> <span class="hljs-function"><span class="hljs-title">message</span>(<span class="hljs-variable">FATAL_ERROR</span> <span class="hljs-string">"${PACKAGE_NAME} not found!"</span>)</span><br><span class="hljs-function"><span class="hljs-title">endif</span>()</span><br></code></pre></td></tr></table></figure></p></li></ul></li><li><p>find_path:这个函数一般是查找头文件或其他的 非库文件 且 非可执行程序。其函数原型为: <figure class="highlight prolog"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs prolog">find_path (<br> <<span class="hljs-symbol">FILE_NAME</span>><br> name | <span class="hljs-symbol">NAMES</span> name1 [name2 ...]<br> [<span class="hljs-symbol">HINTS</span> [path | <span class="hljs-symbol">ENV</span> var]... ]<br> [<span class="hljs-symbol">PATHS</span> [path | <span class="hljs-symbol">ENV</span> var]... ]<br> [<span class="hljs-symbol">PATH_SUFFIXES</span> suffix1 [suffix2 ...]]<br> [<span class="hljs-symbol">DOC</span> <span class="hljs-string">"cache documentation string"</span>]<br> [<span class="hljs-symbol">NO_CACHE</span>]<br> [<span class="hljs-symbol">REQUIRED</span>]<br> [<span class="hljs-symbol">NO_DEFAULT_PATH</span>]<br> [<span class="hljs-symbol">NO_PACKAGE_ROOT_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_ENVIRONMENT_PATH</span>]<br> [<span class="hljs-symbol">NO_SYSTEM_ENVIRONMENT_PATH</span>]<br> [<span class="hljs-symbol">NO_CMAKE_SYSTEM_PATH</span>]<br> [<span class="hljs-symbol">CMAKE_FIND_ROOT_PATH_BOTH</span> |<br> <span class="hljs-symbol">ONLY_CMAKE_FIND_ROOT_PATH</span> |<br> <span class="hljs-symbol">NO_CMAKE_FIND_ROOT_PATH</span>]<br> )<br></code></pre></td></tr></table></figure> 一般情况下,由于需要cmake表达式来让cmake判断使用哪个配置的库,我们通常这么写:</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">find_path</span><span class="hljs-params">(<PACKAGE_NAME>_INCLUDE_DIR NAMES header.h PATH_SUFFIXES include/...)</span></span><br><br><span class="hljs-function"><span class="hljs-title">find_library</span><span class="hljs-params">(<PACKAGE_NAME>_LIBRARY_RELEASE NAMES name1 name2)</span></span><br><span class="hljs-function"><span class="hljs-title">find_library</span><span class="hljs-params">(<PACKAGE_NAME>_LIBRARY_DEBUG NAMES name1d name2d)</span></span><br><span class="hljs-function"><span class="hljs-title">select_library_configurations</span><span class="hljs-params">(<PACKAGE_NAME>)</span></span><br>...<br>target_*(target_name ${<PACKAGE_NAME>})<br></code></pre></td></tr></table></figure></li><li><p>find_program:这个函数专门用于查找可执行程序</p></li></ul><h2 id="使用依赖">使用依赖</h2><p>经过了上面的狂轰乱炸,我们终于可以使用依赖项了。我们可以将查找到的依赖项用于多个函数中,例如添加头文件路径,添加链接库,添加编译选项等。</p><p>对于不同的查找方式,配置文件或cmake提供了不同的使用方式:</p><ul><li><p>宏 例如 <PACKAGE_NAME>_INCLUDE_DIRS 和 <PACKAGE_NAME>_LIBRARIES 这种方式。</p><p>对于头文件来讲,直接加到include_directories中就好了。而对于库来讲,则复杂点:</p><p>由于不能混合使用debug库及release库,cmake必须明确知道在不同配置下使用哪个库。所以宏中一般使用到了cmake表达式来处理这种情况,比如: <span class="math inline">\(<\)</span><CONFIG:DEBUG>:library.lib> <span class="math inline">\(<\)</span>{NOT:$<CONFIG:DEBUG>>:libraryd.lib> 所以我们在写配置时,尽量将debug和release库均查找后使用 select_library_configurations 来生成表达式以便不同配置下使用。</p></li><li><p>target target 就简单的多了,因为它是一个object,cmake函数可以轻松提取 target 包含的需要使用的属性来使用。 当然,target 包含非namespace与namespace两种形式,不过使用上没区别。 ## 内部依赖</p></li><li><p>add_dependencies: <figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">add<span class="hljs-constructor">_dependencies(<<span class="hljs-params">target</span>> [<<span class="hljs-params">target</span>-<span class="hljs-params">dependency</span>>]<span class="hljs-operator">...</span>)</span><br></code></pre></td></tr></table></figure> 向前者添加依赖项(后者),可以添加多个。在编译或某些配置时,优先处理后者。</p></li></ul><h1 id="编译相关函数">编译相关函数</h1><h2 id="关键字">关键字</h2><ul><li><p>target target在cmake中是一个很重要的概念,可以理解为一个实例化对象, 一般是由add_executable(),add_library() 或 add_custom_target() 命令之一创建,它包含了例如以下内容:</p><ul><li>相关的源文件列表</li><li>相关的编译选项</li><li>相关的依赖库</li><li>相关的头文件路径列表</li><li>相关的库文件路径列表</li><li>相关的其他属性</li></ul></li><li>PUBLC PRIVATE INTERFACE 例如 target_link_libraries(A [PUBLIC/PRIVATE/INTERFACE] B)<ul><li>PUBLIC 依赖项B仅链接到目标A,若有C链接了目标A,C不链接依赖项B。</li><li>PRIVATE 依赖项B并不链接到目标A,若有C链接了目标A,C会链接依赖项B。</li><li>INTERFACE 依赖项B链接到目标A,若有C链接了目标A,C也会链接依赖项B。 > <a href="https://www.jianshu.com/p/07761ff7838e">CMake 中的 PUBLIC,PRIVATE,INTERFACE</a></li></ul></li></ul><h2 id="相关函数-1">相关函数</h2><ul><li><p>target_compile_options:向目标添加编译选项 <figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs fortran">target_compile_options(<<span class="hljs-keyword">target</span>> [BEFORE]<br> <<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items1...]<br> [<<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items2...] ...])<br></code></pre></td></tr></table></figure> 例如: <figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">target<span class="hljs-constructor">_compile_options(<span class="hljs-params">sample</span> PUBLIC <span class="hljs-operator">/</span><span class="hljs-params">arch</span>=<span class="hljs-params">avx2</span> <span class="hljs-operator">/</span>Wall)</span><br></code></pre></td></tr></table></figure></p></li><li><p>target_compile_definitions:向目标添加预设宏声明及定义</p><figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs fortran">target_compile_definitions(<<span class="hljs-keyword">target</span>><br> <<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items1...]<br> [<<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items2...] ...])<br></code></pre></td></tr></table></figure> 例如: <figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">target_compile_definitions</span><span class="hljs-params">(sample PRIVATE BUILD_DLL PUBLIC <span class="hljs-string">"-DPI=3.14159"</span>)</span></span><br></code></pre></td></tr></table></figure></li><li><p>target_include_directories:声明了编译目标时查找使用头文件的路径。</p><p><figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs fortran">target_include_directories(<<span class="hljs-keyword">target</span>> [SYSTEM] [AFTER|BEFORE]<br> <<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items1...]<br> [<<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items2...] ...])<br></code></pre></td></tr></table></figure></p>例如: <figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">target<span class="hljs-constructor">_include_directories(<span class="hljs-params">sample</span> PUBLIC <span class="hljs-params">public</span><span class="hljs-operator">/</span><span class="hljs-params">include</span><span class="hljs-operator">/</span><span class="hljs-params">sample</span> PRIVATE <span class="hljs-params">sample</span>)</span><br></code></pre></td></tr></table></figure></li><li><p>target_link_libraries:声明了链接时需要参与的依赖库名称或target,其名称可包含完整路径。</p><p><figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs fortran">target_link_libraries(<<span class="hljs-keyword">target</span>><br> <<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items1...]<br> [<<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items2...] ...])<br></code></pre></td></tr></table></figure> 例如: <figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">target<span class="hljs-constructor">_link_libraries(<span class="hljs-params">sample</span> PUBLIC CURL::<span class="hljs-params">curl</span> <span class="hljs-params">glib</span> <span class="hljs-params">m</span>)</span><br></code></pre></td></tr></table></figure> 注意:由于一个target中包含多个属性,一般情况下包含了头文件路径。所以使用target作为参数传入此函数时,无需调用 target_include_directories 再次声明添加头文件路径。</p></li><li><p>target_link_libraries:声明了链接时查找依赖库的路径。 <figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs fortran">target_link_libraries(<<span class="hljs-keyword">target</span>> [BEFORE]<br> <<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items1...]<br> [<<span class="hljs-keyword">INTERFACE</span>|<span class="hljs-keyword">PUBLIC</span>|<span class="hljs-keyword">PRIVATE</span>> [items2...] ...])<br></code></pre></td></tr></table></figure> 例如: <figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs reasonml">target<span class="hljs-constructor">_link_libraries(<span class="hljs-params">sample</span> PUBLIC <span class="hljs-params">third_party</span><span class="hljs-operator">/</span><span class="hljs-params">libs</span><span class="hljs-operator">/</span><span class="hljs-params">x86</span><span class="hljs-operator">/</span><span class="hljs-params">rel</span>)</span><br></code></pre></td></tr></table></figure></p></li></ul><h2 id="target族函数注意事项">target族函数注意事项</h2><p>当需要使用cmake export关键字导出声明的target并附带其中的 PUBLIC 属性时,我们必须 将PUBLIC / PRIVATE / INTERFACE 关键字向这类 target 族函数补齐。且如果一个 target 族函数声明了这三个关键字其中之一,该 target 所属的其他 target 族函数均应当声明关键字。且对于包含路径的值,我们需要声明此值的使用范围:</p><p>编译/链接时使用。必须使用绝对路径。 导出以向下游提供。必须使用相对路径。 所以,我们通常情况下使用以下方式:</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ruby">target_include_directories(sample <span class="hljs-variable constant_">PRIVATE</span> <span class="hljs-variable">$<</span><span class="hljs-variable constant_">BUILD_INTERFACE</span><span class="hljs-symbol">:</span><span class="hljs-variable">${</span><span class="hljs-variable constant_">CMAKE_SOURCE_DIR</span>}/header/<span class="hljs-keyword">include</span>> <span class="hljs-variable constant_">PUBLIC</span> <span class="hljs-variable">$<</span><span class="hljs-variable constant_">INSTALL_INTERFACE</span><span class="hljs-symbol">:include></span>)<br></code></pre></td></tr></table></figure><h1 id="reference">Reference</h1><p><a href="https://www.zhihu.com/column/c_1490802622991306752">CMake教程系列</a></p>]]></content>
<categories>
<category>Programming</category>
<category>C/C++</category>
<category>CMake</category>
</categories>
</entry>
<entry>
<title>Effective Academic Writing</title>
<link href="/Research/Academic-Writing/Effective%20Academic%20Writing/"/>
<url>/Research/Academic-Writing/Effective%20Academic%20Writing/</url>
<content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look."> <script id="hbeData" type="hbeData" data-hmacdigest="1e298c201dc0bfe76af7e192bc1de09f691f714bfdedfe8ecd7bf2ae38a305d6">4630436162ade97ba2718b7d0c4b3b630feb3b48bea4a303f664086afc210114fc615933b47ea0ac7d43594df641b32db65df296f48d3818e31a91a9c53fcca057750c57d14899e794824cc8fb93819f404849cee20ba10291e94c38b919d3dbaab337791e1e529c029a610f27331a77e30f30514fe20d384c11dd81650530bf1fc847d3d1d0fce3ed52b38961ea733bdc26a10f8aad0b35911c90b087962e3a000a2ba52029344ae7ad6879443984a07b7c78a2361e9b9bf8595927e5ad89ab46f9cb606cdc914d315ed9b999e51c4a9702a8f6ff7e6667836d62ed3b31ac802946a279cfa791927cb6dc4975f3b9fa67806664cf8c6f07e37ac1d9c958d6b316fae838cec3696db706edd53927998eeb48e3201e41f8197bb95e389955f8fdfc37cf6762c3b1575fbf92ce4782c858ef878663a8f3d0ef513bee4d4adde2a32c97df46b3d4c53218901f2cdda252515e4820c7f060a8743f8efc6b539951e5885a0ecb06aa8789555596895a55bf63aea461be7f05a63a9b53247a8c6ccbdaeb2bdb2b6bb08cf7b35e401e482841fce1bbd0c6a66110db971b7253f2e1aa4793ec3072431e4e4022b1192ea8b74f6a6ee74edeeb5411a59ab7461f7bf8e0a4ffc093533b6d8602fb088968a599681ccb3246724e8e00f7b5206d85b31972c22abc6b2cd8e99db587ddf7a3b385453bbf04d4b5a6826a9039373eae67744aa90913445517aed45d6812e03b5b7c6a76a1ca17f59b43ab0556c8c80ed9b1a7b09d93aa069531c18d1e5bbee4213b27541db7247500dc8cfb0a0b3695b26a3bb0945c51dde906e383c620a48d1666a4ca4f9aafeabb07f39be99b2bc4fb543479c46420d08c2a8c603d565798c01e6bae3ac7ab0511ae5077c14ac1d7dba1ac6471651f6fde2009e4aeb70b088d98471babf370e07e66b3d83fa5df7f139f4416c62763179ce5b56a772d1c1b2d85830f37588ecde6aad3fd06a80e94b016d9f1d850ed6a900cda8039c9d6fa1ff20b46e55603df59c711b9fabd3c60f089da7702d244e43fa70350753f6f1d41f0acd7636d2cdbec98fdb0141d93f7073f8dd1650e0e6074f37fdb94098c3d3bda6392dbd4136fd5e4e842652d46165a3d95c4a45b872738398b42c532fa6764d1d567c617524cc1b81678f765394fd56d6f28a503fe40b2af0bdcb0de45c41f3a57d0ae5b81fbc71f134f638d49f9f195f61d5852d933ecdd18bd4151f0ea87eb41371ed626b20a5c6e08074a6e8534f89394bb681d531e0671971e5f1ceb6d7908df71c4d2d609477622008fbb395b6f9df3671628eabb7c5d83bf65e2ec00abf62cab3630e4740c19ce9dc0bc10f5f91c0db848fc9b6cc8bd557f7246687e3e076811af86e9e0b3e0cfed05f07b477908a7465b463905c62edf0c8389549262087ce96447516d11ea65f016ab72ceeb4210648e9812ba82867fa12f2a9b54497f844293d50aa5627954fc064bdb362c4671dad0274538a1e6e1175418f02e881744c57510736c522f190a233623a7ef9cdeee13b3c81138fc2d0f290de728a4162d79804d3b3bd1b397157dbdf23c20f285cd2279bf6ff70369e34bb43a90428ada6b462911fc4577ba00e9481509f04fb264b3bd3dd64f3b72d797c0bd0b95c9d8b4fa6c31cb3cf7ca501470d5cacf081cf6d3314db0624055d2ea17c433918afd45d608fd36a2a5c56ed2a26cc5c7b82c9065750a105dbeac296d7bcd9c726664913c45ca38e2ce1988ee4418fd3722af959d080b54e335715288b26863316980f1cb8646dd1c28bdce3ef5dfece95102adf32a2f3a0ff124103989c097102cada7c8e733ff2bcdc0e79b348ed52adb7d293cbb621a683d46543a2b52e75bae0e8066429a21b3f133ad44348aec5796e272d33828c83884fd970299f76fa98a458967e19856ac01ab81ecaa891924f6e41aaa7b0da457d1cd2e5c267c9a893d33565963cf1436af07eb2f25db41fdf92b9807acba9b602e296caa9cd9b134e308f93505407f71a47504d15b2bf04e36c4ddf37f8d6af13590def34ebaf156e1b98d42520db39a01682ea09efb1d90e80840c73cf1a1361d90a8c650158ff227a924432ebbc930483887df3d87dca8a848bb1e85ded297f04dd8936da46efd9066d4efb66eb61158a06f70d66e329f3cbeb1325298722ab46138519808e434251726ba8ae02c6bb17147151100742a2c574ae86566aef927476832230be466e85b833033ed772f6a666bd6a243372355c12a25d7582ca36050f988ac1b1b22267c97820709e350531eab45a26ef44c023941895357077e7c21edd67586a6d2e91178962bf9f9590c509fc510fda6bf1956e3db301dcff92fc4a99eb13e92386ad5218eae3f087b086e5c38415ee2509ef87c6c3a999bc5fc3913ce8f6b719e09920b96c77366665129269d01fdbfe3ec43173f4e1bb1ee51851b9e97b257337ad515c0df86936334b619fd1ed5f8211637d3881ae6b1dc80481a82c95e99e9f0f057777d872278cecbd54f82771c2be3b95f3c0469dcc11b8acf89b75b2bb54a24d8cd1bd0bb230ffb655605a122639043e506aa591fc8d392a474f9dd87a7bf5e605e87ac01014ab3c2ca243d245d254d01437a80815c46096fad66b99d110c093ed164e0a046e5455ec3ba4ff8c886421fc60193d4bbd989ee344cf6b7ff5fae24c0e15e850edcadaf0bef482cd3178cce04a769d03717881b04439387f003082aa0feffeb8a05a3809c2830c57243c241d777abf664be28500d3f0a2ab8ed27b2eddbe9e4b098b403fdfbcdb2b2a63e2a61505f5462cefe6818ef26554483372f56ec0002723c0a7fcefc3927a4187934866ca210ee0ae5cbe16e38c21f4e1384581875b06321abd1a9ebd8b65fde5f44c3b6cb6365a38b7b188f759020bf23600f8ab4665d06dffcd8b0be0f4d28f11ceb8aa700082434ecabcee8aae1bf7a7782088864e42eb85bc61d2c7f2850ae12d7fbb6a85d8c854196934a075603f51f6d48c53afb4ca3c3dd23e5bed7e7ec6beca8ec7db625834ac31ebb6e1c82a6e94a47f5b9a8689d0b0da7815759419b9fc58dfd68b23a0c772b140a71882859fd4dc15e8523ddf09d76fe27c8b9c689b2e65564300556274db82f291f7db7523b2840210d0f49d49c93faf857cd946ee4344a8623334d4fe24a05c795624ff10a0cc54e1b9e80f6153f4660b553fbd6b67705c3e96653860cd1eac31dcba95fe1f0755b5a2feea9a140cb036bfb90e5628cfbf7d3ea01e78bceac866ed3111b42a57b3894bfea448c596f3ac71c82a1bb5612e311546ea96344688f7628f1ece97181fb182c807dcf5ff05ab5c4ee7513f1fbe91b5247847b73193c8d28a93a0b200198818d83e3a94fa8ae2f9be89e58f8e2e2617ef242f8fa74cb3ca6de8e0db805dc64cf7a0f3f2a68acfc7b2e80f656cb714ecbfb9b471a21f97d8f9df160e49f0ba56142158b324ab1e639174bd544c47a851274e37e906b8c0e0ddc67dcb2a5d7aaaf6c694186d117f03c759aa301a7da4f493fdf8a0b53d695273e3199476193c4b3e2fbecf2810cda24d5b9ad04e989d43c647345f24c9f9c62615b26cabacf1cca9303bfa6532ebcfc9d490e119cf6b5233816250c4e6e90548b19205e61d78cabc5adfb37cea830d5501453815d22105f2a613558ae9ed0eb71c3c9a55895ec7d961b4c856a92f17ab286a7d2da34484391943ee4c867455f08fac5cac00e1560f574d48db42cd8a5867ffabbfba78eac886604c90df0df895572c7bcc9981212592c5a645423a0a688a09fe4a22d2fb4774e8c0cff9b0cb01b477ad961c2277f36710c37208ed52f4eb496d0d55e4bb0b4917412b50f3f81ce809ae6c33f2c243beb6a63806cd675378ca0b288c530055fbcfd7e9b90e252002b1137de75a49d53c052bc42fa3627b059a61c9d2fefff95c5717b599598d2d8087317ac0ef6421ee6fba689fcf164ded6e0b5f55e451405b27672958a7017a807dcb2e888d8be236193bb5781cca6dcd0bf632465f2892842f22de44e6f938acd4d43b351f7055560ce09959651e6973d05a41258534343b36640ad23e8c54115951a96308e276184b7203e685b612f7e6875459b51b12c28036b123c043121ede5106ea28cb4b1bc7abaf536d54a914a0850bff1f81724752d8343e2bda16d37b3528f1e50b89b50e58d7233178b297ca3463bfbad9f1e2fd05b334f8a3609e83d921c8a6ff22a7aaa868930b5a96d4bb058d3d2279c187a39d1ea7a663c6db025aa9ce2ca4d559a8112a3689ee908b69d1d4cdbc1f060f45d075588ee2a7fd6d97768940b01eb6513bfc686a0c782c3388f75166135bb848725843a4fa3bc725b458d9c81484ac8a9e8135e0c39b31c97d835709fb4912cbb62608dc88a4982af88286a947a215fd8d5c341bb67adcfd215209356a54c843c314ad8a4178192258e78c41a12a0629248c375c1817155a07de1e12aa2bfd8f86c3b2ea7f0df5edc44f191978442cf359df22d441f46a936ac8dedcdc4b2e85f422f824bea1fe2eea19bf4d7468d7623254e6ad3ba5ee29298c14d945ab8460d25bd7943adcf48358557bbb22c2cba7db519b59b20320663a7809f7efcefd2378e3d73bf1d8acd63fd9ee95c881b9bd818f6827f8069f50154cce163a6cbe04c7ea4d933c9d2a967fef6a192df74429895fb3df7692456f1d7dba089ec84c2980be5591038f0e3763befb620beeded990b5aabced09094d2a047ccae7bc456157c4387b91a352b809cf02a08b64765024bc230f7c75395a2dad6991eaa3314fa6ef30a0adeeaf2a26dc8443317cb5f8387780f6a9fe30bf1c207b421d708eb7c2003525c6a0f4ff773978ae804f0964b90a7c7d2118a60d323d3ba0658678f05edf77fd8b167c9547fa26cac0d2e55b14b9ba0f61e2e1a5abd702a8c95553de5986b4a13927b3830d05843a3a6c96d554ce6bf6799184d9bbc6b5f41641102eeef8324dcac7ec9e43a227081524084f290f7ac160fbe604eea368a4af50418292dce242a9f6cb50c8a751ce622bac7486459f69ddd7c3f75ba8bb6fe9bbd529eb5d1075448150df59df9a34e8496d8a54349c50f40ee8b70f2af0c6edf3b35f2e02dc86003af56cf1d05347811c85af894191675a3c3bd3b481017873c17266e13307fad82f8ae19defc29a7c137c87367ac1b6cef641765cae7302041e41d2f3418d9df3cd53fb3dee2f74a40652a0420352ac8694b77a4e314e987507a330fefd42547c92ef15282b87a04c5786ef5992301c1564ab1265c88b5309a6760db091ac9db85ccd98d7cef3cde148913e189e4b8bfe822e19e1b811a257d6572e16caae83d10fe03af3e3731dd64f0db4f22db64e759cb4914138ffb5f9ecedcb76b090cbb27359ce3a333ec37a50ba0bfe44b2351784249a08299b95a9d9052d6bcdd01deebdb66f04278014612586c2b95b5e3de394ed7a5bf92a29c2adc5d20bbb49e6c43ea17166919d758778b4775d5fbd2f0664ecfc5e91424f53042b6a52020e57c9908113151c62ee75e8a24801208f5e1de7ba2775949b28439d0b0554ca1c85985e3c73ec4cdd262167080eb4c126ff6d90dacf3d403005648e7535e6015b1050ba12b870f02a799ed87906ad5d7513d589cf91d78dc0e82651dbe339c30aba154e7d8f551568213096aed457903d368c03eea1bc5a8f12bec914e23f7835947aa5565ae26849d456079b05c9d2a333dcd395350451fe1101ab371b1d17d11ef156e8e8518990757277c9b016e527672c1c149c82b673853aa0f2c9ae9af3dd14066b0d518bf7d85006b9e2889aa1b22991b8890cafe8c8d2e09f2a72cb295c121e287</script> <div class="hbe hbe-content"> <div class="hbe hbe-input hbe-input-default"> <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass"> <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass"> <span class="hbe hbe-input-label-content hbe-input-label-content-default">Welcome to my blog, enter password to read.</span> </label> </div> </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<categories>
<category>Research</category>
<category>Academic Writing</category>
</categories>
</entry>
<entry>
<title>Dive into DL</title>
<link href="/Artificial-Intelligence/DL/Dive%20into%20DL/"/>
<url>/Artificial-Intelligence/DL/Dive%20into%20DL/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://chenxindaaa.com/Programming/Python/PyTorch/Dive%20into%20DL/Dive%20into%20DL-Linear%20Regression/">Linear Regression</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/DL/CV/Dive%20into%20DL/Dive%20into%20DL-Softmax%20Classification/">Softmax Classification</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/DL/CV/Dive%20into%20DL/Dive%20into%20DL-Multilayer%20Perceptron/">Multilayer Perceptron</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/DL/NLP/Dive%20into%20DL/Dive%20into%20DL-Text%20Prepare/">Text Prepare</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/DL/NLP/Dive%20into%20DL/Dive%20into%20DL-Language%20Model/">Language Model</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/DL/NLP/Dive%20into%20DL/Dive%20into%20DL-Recurrent%20Neural%20Network/">Recurrent Neural Network</a></p>]]></content>
<categories>
<category>Artificial Intelligence</category>
<category>DL</category>
</categories>
</entry>
<entry>
<title>C/C++ Cookbook</title>
<link href="/Programming/C-C/C++%20Cookbook/"/>
<url>/Programming/C-C/C++%20Cookbook/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://chenxindaaa.com/Programming/C-C/C++%20Cookbook/STL/">STL</a></p><p><a href="https://chenxindaaa.com/Programming/C-C/C++%20Cookbook/GDB/">GDB</a></p><p><a href="https://chenxindaaa.com/Programming/C-C/C++%20Cookbook/inline/">inline</a></p><p><a href="https://chenxindaaa.com/Programming/C-C/C++%20Cookbook/Move/">inline</a></p><p><a href="https://chenxindaaa.com/Programming/C-C/C++%20Cookbook/Lambda%20Expression/">Lambda Expression</a></p>]]></content>
<categories>
<category>Programming</category>
<category>C/C++</category>
</categories>
</entry>
<entry>
<title>Machine Learning</title>
<link href="/Artificial-Intelligence/ML/ML/"/>
<url>/Artificial-Intelligence/ML/ML/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLeaning_PCA/">PCA</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_AdaBoost/">AdaBoost</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_FP-growth/">FP-growth</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_K-NN/">K-NN</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_LogisticsRegression/">Logistics Regression</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_NoiveBayes/">Noive Bayes</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_Regression/">Regression</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachinLearning_Apriori/">Apriori</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachinLearning_Cluster/">Cluster</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachinLearning_DecisionTree/">Decision Tree</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachinLearning_SVM/">SVM</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_AHP/">Analytic Hierarchy Process</a></p><p><a href="https://chenxindaaa.com/Artificial-Intelligence/ML/ML/MachineLearning_FCE/">Fuzzy Comprehension Evaluation</a></p>]]></content>
<categories>
<category>Artificial Intelligence</category>
<category>ML</category>
</categories>
</entry>
<entry>
<title>Python Cookbook</title>
<link href="/Programming/Python/Python%20Cookbook/"/>
<url>/Programming/Python/Python%20Cookbook/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://chenxindaaa.com/Programming/Python/Python%20Cookbook/Decorators/">Decorators</a></p><p><a href="https://chenxindaaa.com/Programming/Python/Python%20Cookbook/classmethod,staticmethod,property//">classmethod, staticmethod and property</a></p>]]></content>
<categories>
<category>Programming</category>
<category>Python</category>
</categories>
</entry>
<entry>
<title>MATLAB</title>
<link href="/Programming/MATLAB/MATLAB/"/>
<url>/Programming/MATLAB/MATLAB/</url>
<content type="html"><![CDATA[<meta name="referrer" content="no-referrer"/><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础01.%20.m文件/">Matlab基础01. .m文件</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础02.%20条件循环/">Matlab基础02. 条件循环</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础03.数据类型/">Matlab基础03.数据类型</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础04.结构数组/">Matlab基础04.结构数组</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础05.多维数组/">Matlab基础05.多维数组</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础05.多维数组/">Matlab基础05.多维数组</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础06.第三章习题/">Matlab基础06.第三章习题</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础07.二维图/">Matlab基础07.二维图</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础08.三维图/">Matlab基础08.三维图</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/Matlab基础09.%20图形属性设置及习题/">Matlab基础09. 图形属性设置及习题</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/matlab基础10.线性代数/">matlab基础10.线性代数</a></p><p><a href="https://chenxindaaa.com/Programming/MATLAB/MATLAB/matlab基础11.matlab在微积分中的应用/">matlab基础11.matlab在微积分中的应用</a></p>]]></content>
<categories>
<category>Programming</category>
<category>MATLAB</category>
</categories>
</entry>
</search>