我正在研究“设计模式解释”中的一个桥接模式的例子。我正在查看的示例是示例10.3,可以在
http://www.netobjectives.com/resources/books/design-patterns-explained/cpp-code-examples/chapter10#10-3
我特别困惑的是Shape类及其派生类。
#pragma once
#include "Drawing.h"
class Shape
{
public:
Shape(Drawing *aDrawing);
virtual void draw()= 0;
protected:
Drawing *myDrawing;
void drawLine( double, double, double, double);
void drawCircle( double, double, double);
public:
~Shape(void);
};在Circle类中,我们有
#pragma once
#include "Shape.h"
class Circle : public Shape
{
public:
Circle(Drawing*, double, double, double);
virtual void draw();
virtual void drawCircle(double, double, double)=0;
public:
~Circle(void);
protected:
double _x, _y, _r;
};所以我的问题是:既然方法实际上是在基类中实现的,那么为什么drawCircle在继承的类中可以是纯虚的呢?
发布于 2013-09-15 18:27:17
想象一下,你正在构建一个使用不同API (windows GDI,一些智能手机API,OpenGL,任何东西)绘制形状的模块。对于典型的层次结构、<--- concrete Circle和abstract Shape <--- concrete Rectangle,每次添加新框架以及现有框架中的某些更改时,都必须重新编译和重新部署Circle和Rectangle。这样的更改甚至可能涉及修改这些类的构造函数,因此模块的用户也必须更改他们的代码。
示例:您有一个可以正常工作的模块的第一个版本,具有用于Circle的以下接口
class Circle : public Shape
{
public:
Circle(int x, int y, int radius);
void draw(...);
};然后,由于某个平台的优化原因,你不得不提前知道当前平台的DPI分辨率(在实际绘制圆圈之前)。因此,您必须更改构造函数:
class Circle : public Shape
{
public:
Circle(int x, int y, int radius, int dpi);
void draw(...);
};而你的代码的客户将不得不重新编译他们的应用程序。当然,有一些黑客可以避免这一点(比如引入CircleWithDpi),但它们将导致高度耦合和难以维护的代码。如果你使用桥模式,你可以保持清晰的设计,同时仍然表达你的领域(一般来说,“圆”的概念不应该知道任何关于"dpi分辨率“的东西)。
因此,拥有:
class Circle : public Shape
{
public:
Circle(int x, int y, int radius);
virtual void draw(...) = 0;
};和
class CircleImpl : public Circle
{
public:
CircleImpl(int x, int y, int radius, int dpi);
//perform some calculations before drawing for optimization
void draw(...);
//draw using appropriate API
};和
class ShapeFactory
{
public:
virtual Circle* CreateCircle(int x, int y, int radius) = 0;
};当然,您会有许多CircleImpl-每个都对应于您的模块支持的不同平台(so、CircleImplGDI、CircleImplTk、CircleImplOpenGL等)。
在ShapeFactory的实现中,您将适当地创建一个特定的CircleImpl,并且您的模块的客户端不必知道任何关于它的信息。此示例是您提供的链接的简化版本。注意,现在,当可能的CircleImpl之一被用作Circle时,没有抽象类被实例化,所以这也应该解决您关于抽象派生类的问题。
此模式背后的主要思想是具有两个级别的抽象:Shape是一个抽象的几何概念,Circle和Rectangle比Shape更具体,但在绘制它们的许多技术可能性的上下文中,它们仍然相当抽象。当你知道上下文时,特定形状的具体表示就存在了:例如,在光栅上绘图或使用矢量图形。
另一层抽象让你有可能推迟更多关于你的代码的决定--首先,我们推迟了关于我们拥有的形状的决定。然后,有了Circle和Rectangle,我们推迟了如何绘制它们的决定。延迟决策为我们提供了解耦的、灵活的代码(如“添加的DPI”示例所示)。
发布于 2013-01-23 16:48:44
纯虚方法在任何类中都是允许的,只要您不尝试创建该类的实例。
https://stackoverflow.com/questions/14475513
复制相似问题