作者leondemon (狗狗)
看板OOAD
標題Re: [請教] 請教strategy、state pattern in C++
時間Sat Apr 23 17:40:45 2011
我不懂C++ 也看不太懂你的問題
但是如果一個龐大的class內部有許多需求需要改變的時候 一般會用下面作法:
原本狀態:有一個物件叫做Computer
他有9種方法(method1-method9)以及5種實體變數(ivar1-ivar5)
用pseudo-code表示:
class Computer:
@attribute(public) ivar1 //為public的attribute
@attribute(public) ivar2
@attribute(public) ivar3
@attribute(private) ivar4 //為private的attribute
@attribute(private) ivar5
-method1 #public > block1 //表示method1內部使用block1的演算法邏輯 以下類推
-method2 #public > block2
-method3 #public > block3
-method4 #public > block4
-method5 #public > block5
-method6 #public > block6
-method7 #public > block7
-method8 #public > block8
-method9 #public > block9
end
通常我遇到這麼大的class我第一步都是在class前方先寫註解
來敘述這個物件的responsiblity
現在你希望你維持同樣的public interface給使用這個類別的人使用 又有改變的需求
假設method4-method6和method7-method9都有改變需求但改變動機和時機不同
作法會變成宣告兩個新的Helper物件:
class HelperA:
-method4 #public > block4
-method5 #public > block5
-method6 #public > block6
end
class HelperB:
-method7 #public > block7
-method8 #public > block8
-method9 #public > block9
end
class Computer:
@attribute(public) ivar1
@attribute(public) ivar2
@attribute(public) ivar3
@attribute(priavte) ivar4
@attribute(private) ivar5
@attribute(private) HelperA instanceOfHelperA
@attribute(private) HelperB instanceOfHelperB
-method1 #public > block1
-method2 #public > block2
-method3 #public > block3
-method4 #public >
instanceOfHelperA.method4
-method5 #public >
instanceOfHelperA.method5
-method6 #public >
instanceOfHelperA.method6
-method7 #public >
instanceOfHelperB.method7
-method8 #public >
instanceOfHelperB.method8
-method9 #public >
instanceOfHelperB.method9
end
但是因為HelperA和HelperB都需要Computer的ivar3-ivar5的資料
於是必須多一個wrapper來當物件之間的傳遞:
class DataWrapper:
@attribute(public) ivar3
@attribute(public) ivar4
@attribute(public) ivar5
end
clas
@attribute(public) ivar1
@attribute(public) ivar2
@attribute(public) ivar3 > instanceOfDataWrapper.ivar3
@attribute(private) ivar4 > instanceOfDataWrapper.ivar4
@attribute(private) ivar5 > instanceOfDataWrapper.ivar5
@attribute(private) DataWrapper instanceOfDataWrapper
@attribute(private) HelperA instanceOfHelperA
@attribute(private) HelperB instanceOfHelperB
-method1 #public > block1
-method2 #public > block2
-method3 #public > block3
-method4 #public > instanceOfHelperA.method4(instanceOfDataWrapper)
-method5 #public > instanceOfHelperA.method5(instanceOfDataWrapper)
-method6 #public > instanceOfHelperA.method6(instanceOfDataWrapper)
-method7 #public > instanceOfHelperB.method7(instanceOfDataWrapper)
-method8 #public > instanceOfHelperB.method8(instanceOfDataWrapper)
-method9 #public > instanceOfHelperB.method9(instanceOfDataWrapper)
end
當然HelperA和HelperB的method所吃的參數也要改變
class HelperA
-method4
(DataWrapper) #public > block4
-method5
(DataWrapper) #public > block5
-method6
(DataWrapper) #public > block6
end
class HelperB
-method7
(DataWrapper) #public > block7
-method8
(DataWrapper) #public > block8
-method9
(DataWrapper) #public > block9
end
現在你就可以subclass HelperA和HelperB來解決龐大Computer要改變的問題
不知道有沒有解決你的問題
--
看一下你的問題 你應該只需要一個private的data wrapper當參數傳送就可以解決
(如果你只需要知道原本物件的data的話)
不然我上面的例子HelperA和HelperB就必須知道Computer的存在
而且那些會用到的attribute必須是public
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.80.73.25
推 iamstudent :就是不希望都寫成public呀 04/23 17:50
→ leondemon :所以 我這篇講的不是你要的嗎? 04/23 17:55
※ 編輯: leondemon 來自: 111.80.73.25 (04/23 17:57)
推 iamstudent :的確不是,這樣那個大class的內容整個都暴露出來了 04/23 17:57
→ leondemon :抽出來之後的public介面還是跟原本的一樣 04/23 17:57
→ iamstudent :你例子裡面的Computer,我希望他所有attr都是private 04/23 17:58
→ iamstudent :然後只有你的Helper或是DateWrapper可以存取 04/23 18:00
→ iamstudent :因為其他的class或是client都可以使用Computer 04/23 18:00
→ iamstudent :只讓有關的類別可以存取就好,其他人只應該持有 04/23 18:01
→ leondemon :Helper和DataWrapper都是private這樣不行嗎? 04/23 18:18
推 iamstudent :就我目前的case,那個Helper一定會是private沒有問題 04/23 18:25
→ iamstudent :問題是那個DataWrapper,他幾乎會整個等於大class 04/23 18:26
推 iamstudent :不過我好像有點想法了,也許就整個成員抽出去 04/23 18:30
→ iamstudent :我在想,如果把資源物件改放在Helper的super類別... 04/23 18:32