自学内容网 自学内容网

设计模式——空对象模式

定义

空对象模式(Null Object Pattern)是一种软件设计模式。在 C++ 中,它主要用于用一个空对象来代替 NULL 引用的检查。这个空对象可以提供默认的行为,从而避免了在代码中频繁地进行空指针(NULL)检查。
例如,在一个图形绘制系统中,如果没有指定图形的颜色,不是返回一个空指针(这会导致很多地方需要检查是否为空),而是返回一个表示 “无色” 的空对象,这个空对象有自己的默认行为,比如在绘制图形时不进行任何颜色相关的操作。

结构组成

  • 抽象基类(Abstract Class):
    定义了接口,这个接口包含了真实对象和空对象都需要实现的方法。例如,在一个文件读取系统中,抽象基类可能定义了read()和close()等方法,这些方法无论是对于真正的文件对象还是空文件对象都有意义。
  • 真实对象类(Concrete Class):
    实现了抽象基类中定义的接口,提供了真实的功能。继续以文件读取系统为例,真实对象类会实现read()方法来从文件中读取内容,close()方法来关闭文件。
  • 空对象类(Null Class):
    同样实现抽象基类的接口,但是它的方法实现通常是提供默认行为或者不执行任何操作。在文件读取系统中,空对象类的read()方法可能返回一个空字符串或者特定的错误码,表示没有读取到任何内容,close()方法可能什么都不做。

工作原理

当客户端代码请求一个对象的服务时,它不需要知道这个对象是真实对象还是空对象。空对象会按照其预定义的默认行为来响应请求,而真实对象则会执行实际的功能。
比如,在一个游戏角色系统中,角色有一个武器装备接口。如果角色没有装备武器,不是返回一个空指针,而是返回一个空武器对象。当游戏逻辑调用武器的 “攻击” 方法时,真实武器对象会执行攻击计算等操作,而空武器对象的 “攻击” 方法可能只是返回一个表示 “没有造成伤害” 的值或者打印一条 “没有武器,无法攻击” 的消息。
代码示例
首先是抽象基类,以汽车驾驶接口为例:

class CarDriveInterface {
public:
    virtual void drive() = 0;
    virtual void stop() = 0;
};

真实对象类,比如普通汽车类:

class NormalCar : public CarDriveInterface {
public:
    void drive() override {
        std::cout << "正常驾驶汽车。" << std::endl;
    }
    void stop() override {
        std::cout << "汽车停止。" << std::endl;
    }
};

空对象类:

class NullCar : public CarDriveInterface {
public:
    void drive() override {
        std::cout << "没有汽车,无法驾驶。" << std::endl;
    }
    void stop() override {
        std::cout << "没有汽车,无需停止。" << std::endl;
    }
};

客户端代码使用示例:

class CarOwner {
private:
    CarDriveInterface* car;
public:
    CarOwner(CarDriveInterface* c) : car(c) {}
    void driveCar() {
        car->drive();
    }
    void stopCar() {
        car->stop();
    }
};

在main函数中使用:

int main() {
    CarDriveInterface* normalCar = new NormalCar();
    CarOwner owner1(normalCar);
    owner1.driveCar();
    owner1.stopCar();
    CarDriveInterface* nullCar = new NullCar();
    CarOwner owner2(nullCar);
    owner2.driveCar();
    owner2.stopCar();
    return 0;
}

在这个例子中,CarOwner类不需要判断它持有的car对象是真实汽车还是空汽车,因为空汽车对象已经有了自己的默认行为。

优点

  • 减少空指针检查:
    可以使代码更加简洁,减少了大量的空指针检查逻辑。在复杂的系统中,如果到处都需要检查对象是否为 NULL,代码会变得很杂乱,使用空对象模式可以避免这种情况。
  • 提高代码可读性和可维护性:
    代码的逻辑更加清晰,因为不需要频繁地处理特殊的空情况。例如,在一个员工管理系统中,如果没有员工对象就返回一个空对象,而不是 NULL,其他模块在调用员工相关的方法(如 “工作”“休息” 等)时,不需要复杂的空指针检查,直接调用方法即可,代码的可读性得到了提高。
  • 增强代码的健壮性:
    降低了因为空指针引用而导致程序崩溃的风险。即使在某些情况下对象不存在或者没有初始化,空对象的默认行为也可以让程序继续稳定地运行,而不是因为空指针异常而终止。

缺点

  • 增加类的数量:
    需要创建一个额外的空对象类,对于简单的系统来说,这可能会使代码看起来有些臃肿。如果有很多不同类型的对象都需要空对象模式,会导致类的数量显著增加。
  • 可能隐藏错误:
    如果空对象的默认行为没有设计好,可能会掩盖一些本应该被发现的错误。例如,在一个计算系统中,如果空对象的计算方法总是返回 0,可能会导致用户误以为计算是正确的,而实际上是因为使用了空对象而没有进行真正的计算。

原文地址:https://blog.csdn.net/chuliling0446/article/details/144006017

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!