Re: [請教] 請教strategy、state pattern in C++

看板OOAD作者 (狗狗)時間13年前 (2011/04/23 17:40), 編輯推噓4(409)
留言13則, 2人參與, 最新討論串2/7 (看更多)
我不懂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

04/23 17:50, , 1F
就是不希望都寫成public呀
04/23 17:50, 1F

04/23 17:55, , 2F
所以 我這篇講的不是你要的嗎?
04/23 17:55, 2F
※ 編輯: leondemon 來自: 111.80.73.25 (04/23 17:57)

04/23 17:57, , 3F
的確不是,這樣那個大class的內容整個都暴露出來了
04/23 17:57, 3F

04/23 17:57, , 4F
抽出來之後的public介面還是跟原本的一樣
04/23 17:57, 4F

04/23 17:58, , 5F
你例子裡面的Computer,我希望他所有attr都是private
04/23 17:58, 5F

04/23 18:00, , 6F
然後只有你的Helper或是DateWrapper可以存取
04/23 18:00, 6F

04/23 18:00, , 7F
因為其他的class或是client都可以使用Computer
04/23 18:00, 7F

04/23 18:01, , 8F
只讓有關的類別可以存取就好,其他人只應該持有
04/23 18:01, 8F

04/23 18:18, , 9F
Helper和DataWrapper都是private這樣不行嗎?
04/23 18:18, 9F

04/23 18:25, , 10F
就我目前的case,那個Helper一定會是private沒有問題
04/23 18:25, 10F

04/23 18:26, , 11F
問題是那個DataWrapper,他幾乎會整個等於大class
04/23 18:26, 11F

04/23 18:30, , 12F
不過我好像有點想法了,也許就整個成員抽出去
04/23 18:30, 12F

04/23 18:32, , 13F
我在想,如果把資源物件改放在Helper的super類別...
04/23 18:32, 13F
文章代碼(AID): #1DifwWeJ (OOAD)
文章代碼(AID): #1DifwWeJ (OOAD)