我正在做一個OO框架的設計,我正面臨以下問題。面向對象的設計問題,Liskov替換原理
比方說,在框架中我有一個形狀界面,用戶可以自由地實現和擴展(添加新的功能)的形狀接口來創建自己的數字,例如Square and Circle。爲了使這些新對象可用,用戶必須將它們註冊到指定形狀(字符串)和對象的名稱的ShapeFactory中。
此外,框架提供了一個名爲ShapeWorker的接口定義瞭如下功能:
class ShapeWorker
{
public:
void processShape(Shape& shape) = 0;
};
在使用者自由地實現所述ShapeWorker界面,使特定形狀的工人,例如SquareWorker and CircleWorker。要使這些新對象可用,用戶必須將它們註冊到WorkerFactory中,指定形狀(字符串)和對象的名稱。
在某一點上,框架,賦予代表形狀的名稱的字符串,創建一個新的形狀,通過使用ShapeFactory,事後(代碼中的其他地方)創建一個新的ShapeWorker,通過使用具有相同形狀名稱的WorkerFactory。然後調用processShape提供以前創建的Shape實例。
[ ... ]
Shape* myShape = shapeFactory.create(shapeName);
[ ... ]
ShapeWorker* myWorker = workerFactory.create(shapeName);
myWorker->processShape(*myShape);
[ ... ]
的一點是,這樣做,我強迫實現用戶,例如,SquareWorker做出向下轉換從形狀到廣場到processShape功能,所以訪問完整的廣場的接口:
class SquareWorker
{
public:
void processShape(Shape& shape)
{
Square& square = dynamic_cast< Square& >(shape);
// using Square interface
}
};
這是對里氏替換原則。
現在,這種做法是錯誤的嗎?更好的解決方案是什麼?請注意,我不想執行processShape作爲形狀的成員函數。
我希望描述已經足夠清楚。
在此先感謝您的幫助。
廝磨
你應該添加一個C++標籤我認爲。 – 2010-07-04 19:56:25
您能否提供語句「請注意,我不想將processShape實現爲Shape的成員函數」的原因? – SCFrench 2010-07-04 22:14:13
這裏的一個問題是,引用Shape和ShapeWorker的代碼不知道將形狀傳遞給ShapeWorker是否安全,沒有一些可追溯性返回到創建點來驗證兩個對象是使用相同的shapeName。 – SCFrench 2010-07-04 22:22:48