# POSD Midterm Notes
## ★ __The Open-Closed principle (OCP):__
>Software entities (class, modules, functions, etc.) should be **open for extension**, but **closed for modification.**
+ 一個軟體個體應該要夠開放使得它可以被擴充,但是也要夠封閉以避免不必要的修改。
+ 藉由增加新的程式碼來擴充系統的功能,而不是藉由修改原本已經存在的程式碼來擴充系統的功能
:earth_asia: http://teddy-chen-tw.blogspot.tw/2011/12/2.html
+ 針對 superclass 介面撰寫的程式不再更動,謂之封閉;藉著提供適當的 subclass 實作品而得以產生不同的擴充行為,謂之開放。
## ★ __Principles of reusable object-oriented design:__(P29 ~ 30)
:::danger
1. Program to an interface, not an implementation
:::
+ 不要針對具體實作來設計程式,藉由介面來設計。
+ 善用 polymorphism,利用 supertype 來當作觀察實際變數的窗口,不要把真實 runtime object 寫死在 code 裡面。
+ 設計程式時盡量考慮物件能提供的行為,而非實際的型態是什麼,盡量不要把實際的型態 hard-coding 在程式裡,這樣子能減少模組間的相依性,也能提高擴充性。
:earth_asia: http://yuliang2013.blogspot.tw/2013/03/program-to-interface-not-implementation.html
:earth_asia: http://teddy-chen-tw.blogspot.tw/2010/06/program-to-interface.html
:::danger
2. Favor object composition, over class inheritance
:::
+ **Inheritance**
+ 優:繼承關係程式碼可讀性高,架構容易理解。
+ 缺:繼承關係是在 compile-time 就決定,flexibility 低。
+ 缺:sub-class 有權更動 super-class 內部資料與行為,打破封裝。 反之,super-class 的更動也會影響 sub-class 的行為。
+ **Composition**
+ 優:可以在 run-time 再決定 composition objects,flexibility 高
+ 優:維持 composition objects 的封裝性。
+ 缺:程式可讀性低。
:earth_asia: https://larrysmatchawaffle.blogspot.tw/2012/12/design-patterns.html
首先,類別繼承 (Class Inheritance) 不同於介面繼承 (Interface Inheritance)。
類別繼承重於共享程式碼與內部佈局機制,介面繼承重於可替換性。
假設現在有A,B兩個class, class A中有 method work()
現在要讓B使用A的work() 有以下兩種方法:
|類別繼承 (Class Inheritance)|物件複合 (Object Composition)|
|---|---|
|B extends A ,呼叫繼承來的work()方法|給B一個欄位為class A,並在class B 中給予一個方法去呼叫該欄位的work()|
|破壞封裝性|可在執行期動態指涉(Reference)其他物件|
物件複合使用了稱為delegation(委託)的技術,簡單來講就是把自己該做的事交給別人去做,這樣的方法讓物件複合擁有與繼承一樣強而有力。
:earth_asia: http://hsienwei.github.io/2009/05/05/Object-composition-n-Class-inheritance/
## ★ __CRC = class responsibility collaboration (類別責任合作)__
:arrow_right: 一種物件導向的modeling方式,在建構CRC model時,我們會按照步驟:
1. 找尋class:根據所需要的product或strategy,找尋可能需要的class
2. 找尋class責任:分配好每個class所要負的責任
3. 定義合作關係:若有class需要或修改的資訊是自己本身沒有的,就會和其他class有合作關係
:arrow_right: 以下是CRC cards的範例:


:earth_asia: http://sea-taiwan.blogspot.tw/2012/12/crc-cards.html
## ★ __UDCL__
| | 解釋 | 具體描述 |
|:--------:|:-----------:|:-----------:|
|瞭解問題( U )|understanding the problem|程式的需求為何?具體而言,程式的輸入資料為何?程式的輸出為何?限制為何?|
|規劃解法( D )|devising a plan|列出解決該問題所需做的所有程式待辦工作。|
|依規解題( C )|carry out the plan|一次挑出一個待辦工作,加以完成並驗證。|
|回顧<br/>( L )|looking back|並檢視程式,提出待改善之處,列入待辦工作中。|
:earth_asia: http://htsioop.blogspot.tw/2013/08/introducing-how-to-solve-it-oop.html
## ★ __Delegation__ (P31)

:arrow_right: Defination:
:::warning
a way of making composition as powerful for reuse as inheritance
:::
:arrow_right: advantage:
:::warning
delegation makes it easy to compose behaviors at run-time and to change the
way they're composed. Our window can become circular at run-time simply by replacing its Rectangle instance with a Circle instance, assuming Rectangle and Circle have the same type.
:::
:arrow_right: disadvantage:
:::warning
Delegation has a disadvantage it shares with other techniques that make software more flexible through object composition: Dynamic, highly parameterized software is harder to understand than more static software.
:::
:arrow_right: 中文解釋:
:::warning
Delegation (委派) 大致上可以說是從外部傳 static function 或 class method 進要委派工作的人, 要委派工作的人 run-time 調用 delegate function (compile-time 要委派工作的人並不知道 delegate 是誰), 然後此 delegate function 會依照要委派工作的人的狀態工作. 使用時機就如同上述範例一般: 當要 run-time 決定要對底下所有物件(ex: Book)做不同處理時, 可以用 Delegation.
:::
>"delegation refers to one object relying upon another to provide a specified set of functionalities. In research, this is often referred to as consultation or as aggregation in modeling."
>
:earth_asia: https://larrysmatchawaffle.blogspot.tw/2013/01/delegation-and-its-difference-in-c-and-c.html
## ★ __Stub v.s. Mock - for unit test__
:arrow_right: Stub:在做單元測試時,不會檢查輸入參數,直接定義預期回傳值,不需要設定任何的預期行為
:arrow_right: Mock:在做單元測試時,需要定義function的回傳值以及input參數,且參數是否與期望值符合
:arrow_right: 比較:mock其實方式跟stub很像,stub就像是輕量級版本的mock,不需要透過mock framework或是unit test framework,我們就能達到stub的效果,當你很清楚這一連串動作的預期結果,可以考慮使用功能較強的mock
:earth_asia: http://kojenchieh.pixnet.net/blog/post/75411592-stub%E5%92%8Cmock%E7%9A%84%E6%AF%94%E8%BC%83
:earth_asia: https://dotblogs.com.tw/hatelove/archive/2010/08/14/stub-and-mock-by-nunit.aspx
## ★ __SRP = Single-Responsibility Principle__
:arrow_right: 藉由將介面中不相關的責任(responsibility)移到另外的介面中,也就是說不要讓一個介面『參雜(耦合)』一個以上的責任,基本概念就是 responsibility assignment(責任分配)的問題。
:arrow_right: 英文解釋:
>If a class has more than one responsibility, then the responsibilities become coupled. Changes to one responsibility may impair or inhibit the ability of the class to meet the others. This kind of coupling leads to fragile designs that break in unexpected ways when changed.
:earth_asia: http://teddy-chen-tw.blogspot.tw/2011/12/3.html
## ★ __Pattern__
:::success
### 1. ++**Composite**++ [(P139 ~ P148)](http://www.cs.unc.edu/~stotts/GOF/hires/pat4cfso.htm)
:::
+ Context:你需要在程式中處理部分-整體(part-whole)的樹狀階層式結構。
+ Problem:如何表達部分-整體的階層式結構?
+ Force:
+ 你希望對於單一元素與聚合元素一視同仁。
+ 當新型態的物件被加入到部分-整體的階層式結構中,你希望原有的物件可以儘量不要受到影響。
+ Solution:定義一個元件介面使其包含所有在部分-整體階層式結構中的物件之共同功能,以及用來維持部分-整體階層式結構的功能。所有屬於部分-整體階層式結構中的物件必須實作此介面並維持其遞迴的組成關係。
:earth_asia: http://teddy-chen-tw.blogspot.tw/2013/08/composite-pattern.html


:::success
### 2. ++**Visitor**++ [(P279 ~ 289)](http://www.cs.unc.edu/~stotts/GOF/hires/pat5kfso.htm)
:::
:arrow_right: 定義:Let you define a new operation without changing the classes of the elements on which it operates.
(作用於某個structure中所有元素(class)的操作,可以使我們在不修改各元素的前提之下增加新的操作方式,即為visitor)
:arrow_right: 優點:
+ Visitor makes adding new operations easy
(輕鬆增加新的操作方式)
+ A visitor gathers related operations and separates unrelated ones
(visitor可以收集在不同class內相同的操作,讓其他無關的操作方式分割到他們自己的visitor subclass)
+ Visitor across class hierarchies
(visitor可以traverse整個object structure,即使每個class的型態不同)
+ Visitor can accumulate state as they visit each element in the object structure
(visitor實作traversal時,可以將操作得出的值或狀態進行累加)
:arrow_right: 缺點:
+ Adding new *ConcreteElement* classes is hard
(每新增一個subclass,所有的visitor上都要新增對應的實作)
+ Breaking encapsulation
(破壞原有的封裝性)
:earth_asia: https://wefollownews.appspot.com/cittopnews201408_32/12732.html



:::success
### 3. ++**Builder**++ [(P85 ~ 92)](http://www.cs.unc.edu/~stotts/GOF/hires/pat3bfso.htm)
:::
:arrow_right: 定義:將複雜物件的建構(construction)和表示方式(representation)分開來,使得同樣的建構過程能有不同的表示方式
:arrow_right: 舉例說明:汽車有很多部件(方向盤、輪子、引擎...等等),當我們組成一台車子,組合的過程中很複雜,因此我們需要將部件和組合過程分開
:arrow_right: 使用時機:
+ 給定物件(原料)的構造和物件的組成方式,創造出產品(複雜的物件),當產品可以由不同的componet所組成時,便可以使用builder
+ 利用相同的原料,能建構出不同的產品
:arrow_right: 結論:
+ It lets you vary a product's internal representation
(builder只提供director一個抽象介面,這個介面能讓builder隱藏產品的結構和表示方式,包含產品如何組成的。所以產品的建立僅僅是透過builder提供的抽象介面,想改變產品的內部表示方式,必須再產生出一個新的builder來實作)
+ It isolates code for construction and representation
(Builder藉由封裝複雜物件的建構和表示方式,來達到增強模組化的效果,client端不需要知道class是如何定義產品的內部結構,同樣的此class也不會出現在builder的介面裡)
+ It gives you finer control over the construction process
(不同於其他pattern,builder產品是由director控制之下一步步建構起來,只有當builder完成產品的時候,director才會取回,因此builder的介面比其他pattern更能反映出產品建構過程,讓我們更好控制建構過程和產品結果的內部結構)
:earth_asia: http://www.dotspace.idv.tw/Patterns/Jdon_Builder.htm


:::success
### 4. ++**Template method**++ [(P274 ~ 278)](http://www.cs.unc.edu/~stotts/GOF/hires/pat5jfso.htm)
:::
+ Context:透過繼承的方式可以達到到讓子類別重複使用父類別的程式碼,同時允許子類別覆寫父類別的方法以提供差異化的行為。
+ Problem:要如何表達擁有共同結構與行為,但卻有著些微行為差異的物件們?
+ Force:
+ 為了提供差異行為,如果讓子類別任意覆寫父類別的方法,則:
+ 父類別與子類別以及不同的子類別之間可能會存在重複程式碼。
+ 繼承架構所形成的程式碼將會不容易被理解。
+ 雖然將共同不變的行為定義在父類別之中可以達到重複使用程式碼的目的,若未加以特別區隔則子類別還是可能在有意或無意的情況下覆寫定義在父類別中的共同行為。
+ Solution:在父類別中定義一個範本方法(template method)用以規範共用的行為。Template method將其執行過程委託給數個hook method來完成,子類別可藉由覆寫這些hook method來達到提供不同行為的目的。可將宣告成靜態template method以避免子類別將其覆蓋。
:earth_asia: http://teddy-chen-tw.blogspot.tw/2013/08/template-method-pattern.html

:::success
### 5. ++**State**++ [(P258 ~ 265)](http://www.cs.unc.edu/~stotts/GOF/hires/pat5hfso.htm)
:::
+ Context:一個物件的行為會因為物件自身狀態不同而表現出不同的反應動作,這在程式開發中是一個很常見的情況。例如一個自動販賣機物件,具備「選擇貨品」的功能。同樣一個「選擇貨品」功能,會因為顧客有沒有投錢、投了多少錢,而有著不同的行為反應。
+ Problem:當物件內部狀態改變時,你要如何讓它的行為也跟著改變,就好像這個物件換了另外一個人似的?
+ Force:把所有與狀態相關的程式碼寫在一個物件內可以讓物件依據狀態改變行為,但:
+ 物件的程式碼很容易變得太長,不好理解與修改(而且會違反Open-Closed Principle)。
+ 物件容易存在許多與狀態相關的重複程式碼。
+ 單一物件狀態太多,變得不易測試。
+ Solution:將物件中與狀態相關的行為抽離出來。設計一個State介面,針對每一個狀態,新增一個實作State介面的Concrete State物件。把物件中與狀態相關的行為移到相對應的Concrete State物件之中。讓物件擁有一個指向State介面的成員變數,藉由改變State成員變數所指向的Concrete State物件,來改變原始物件的行為。
:earth_asia: http://teddy-chen-tw.blogspot.tw/2013/07/state-pattern.html

## ★ __Download__
:earth_asia: [2015 POSD 考古題](https://drive.google.com/open?id=0B1bjhJN52iPcbGV2Z1ZqR21hNlk)
:earth_asia: [2015 POSD 考古題解答 by 菡姐](https://drive.google.com/open?id=0B1bjhJN52iPcWkFDbnhrMlUwR0E)
:earth_asia: [Design Pattern CD (GoF)](https://drive.google.com/open?id=0B1bjhJN52iPcZW1UYkUxbU90Tms)
###### tags: `NTUT` `POSD`