我正在做一个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