一、设计模式中的外观模式
- 定义: 外观模式(Facade Pattern)提供了一个统一的接口,用来访问子系统中的一群接口。其目的是简化子系统的使用,消除客户端和子系统之间的耦合,让子系统内部的模块更容易维护和扩展。
- 要点:
- 外观模式不暴露子系统的内部细节,仅暴露一个应用程序所需进行的操作。
- 外观类是客户端与子系统之前的第一层封装,对于多个子系统,客户端可以通过外观类的公共接口依次访问它们。
- 外观模式旨在降低系统的复杂度,其最大的优点就是能够让客户端和子系统之间的耦合度降到最低。
二、C++程序示例说明
1. 示例一
我们来看一个简单的外观模式示例,假设我们有一个计算器程序,里面有加减乘除四个功能,每个功能都需要调用一堆子系统类的方法才能完成,代码如下:
#include <iostream>
class Adder {
public:
int add(int a, int b) {
return a + b;
}
};
class Subtractor {
public:
int subtract(int a, int b) {
return a - b;
}
};
class Multiplier {
public:
int multiply(int a, int b) {
return a * b;
}
};
class Divider {
public:
int divide(int a, int b) {
if (b == 0) {
throw std::exception("Divided by zero!");
}
return a / b;
}
};
class Calculator {
public:
Calculator() : adder_(), subtractor_(), multiplier_(), divider_() {}
int add(int a, int b) {
return adder_.add(a, b);
}
int subtract(int a, int b) {
return subtractor_.subtract(a, b);
}
int multiply(int a, int b) {
return multiplier_.multiply(a, b);
}
int divide(int a, int b) {
return divider_.divide(a, b);
}
private:
Adder adder_;
Subtractor subtractor_;
Multiplier multiplier_;
Divider divider_;
};
int main() {
Calculator calculator;
std::cout << calculator.add(1, 2) << std::endl;
std::cout << calculator.subtract(1, 2) << std::endl;
std::cout << calculator.multiply(1, 2) << std::endl;
std::cout << calculator.divide(1, 2) << std::endl;
return 0;
}
上面这段代码中,四个计算功能分别实现在Adder、Subtractor、Multiplier和Divider类中,而这四个类又组成了Calculator类,作为一个子系统。客户端必须要知道这些类的存在,并且才能使用它们提供的计算功能。这对于客户端来说会很麻烦,因为客户端需要知道子系统内部的实现。
所以,我们可以引入外观模式来简化客户端和子系统之间的交互。我们添加一个新的类CalculatorFacade,把四个计算功能封装成了一个接口,客户端只需要调用这一个接口就可以完成各种计算,如下所示:
#include <iostream>
class Adder {
public:
int add(int a, int b) {
return a + b;
}
};
class Subtractor {
public:
int subtract(int a, int b) {
return a - b;
}
};
class Multiplier {
public:
int multiply(int a, int b) {
return a * b;
}
};
class Divider {
public:
int divide(int a, int b) {
if (b == 0) {
throw std::exception("Divided by zero!");
}
return a / b;
}
};
class CalculatorFacade {
public:
CalculatorFacade() : adder_(), subtractor_(), multiplier_(), divider_() {}
int add(int a, int b) {
return adder_.add(a, b);
}
int subtract(int a, int b) {
return subtractor_.subtract(a, b);
}
int multiply(int a, int b) {
return multiplier_.multiply(a, b);
}
int divide(int a, int b) {
return divider_.divide(a, b);
}
private:
Adder adder_;
Subtractor subtractor_;
Multiplier multiplier_;
Divider divider_;
};
int main() {
CalculatorFacade calc;
std::cout << calc.add(1, 2) << std::endl;
std::cout << calc.subtract(1, 2) << std::endl;
std::cout << calc.multiply(1, 2) << std::endl;
std::cout << calc.divide(1, 2) << std::endl;
return 0;
}
这里引入了CalculatorFacade类,作为客户端和子系统之间的交互层,把四个计算功能封装成了一个接口,客户端只需要和这一个类打交道就可以了,这样客户端和子系统之间的耦合度就降低了。
2. 示例二
再看一下一个更复杂的例子,假设我们有一个情景处理系统,要求实现一个包含多个子系统的日程管理系统。日程管理系统功能复杂,包含了提醒、加密、存储等多个模块,下面我们来看看如何使用外观模式简化这个系统。
首先我们定义了三个子系统类Reminder、Encrypter和Storage,代码如下:
#include <iostream>
#include <string>
class Reminder {
public:
void remind(const std::string& action) {
std::cout << "Reminder: " << action << std::endl;
}
};
class Encrypter {
public:
std::string encrypt(const std::string& data) {
std::string result = data;
std::cout << "Encrypter: " << result << std::endl;
return result;
}
};
class Storage {
public:
void store(const std::string& data) {
std::cout << "Storage: " << data << std::endl;
}
};
这三个类分别实现了提醒、加密和存储功能。然后我们定义了一个类ScheduleManagerFacade,由于项目中要经常访问这三个子系统,所以这个类就成为了他们的管理者,代码如下:
#include <iostream>
#include <string>
class Reminder {
public:
void remind(const std::string& action) {
std::cout << "Reminder: " << action << std::endl;
}
};
class Encrypter {
public:
std::string encrypt(const std::string& data) {
std::string result = data;
std::cout << "Encrypter: " << result << std::endl;
return result;
}
};
class Storage {
public:
void store(const std::string& data) {
std::cout << "Storage: " << data << std::endl;
}
};
class ScheduleManagerFacade {
public:
ScheduleManagerFacade() : reminder_(), encrypter_(), storage_() {}
void createSchedule(const std::string& data) {
reminder_.remind("Create schedule.");
std::string encrypted_data = encrypter_.encrypt(data);
storage_.store(encrypted_data);
}
void updateSchedule(const std::string& data) {
reminder_.remind("Update schedule.");
std::string encrypted_data = encrypter_.encrypt(data);
storage_.store(encrypted_data);
}
void deleteSchedule(const std::string& data) {
reminder_.remind("Delete schedule.");
std::string encrypted_data = encrypter_.encrypt(data);
storage_.store(encrypted_data);
}
void viewSchedule(const std::string& data) {
reminder_.remind("View schedule.");
std::string encrypted_data = encrypter_.encrypt(data);
storage_.store(encrypted_data);
}
private:
Reminder reminder_;
Encrypter encrypter_;
Storage storage_;
};
int main() {
ScheduleManagerFacade scheduleManagerFacade;
scheduleManagerFacade.createSchedule("This is a new schedule.");
scheduleManagerFacade.updateSchedule("This schedule has been updated.");
scheduleManagerFacade.deleteSchedule("This schedule has been deleted.");
scheduleManagerFacade.viewSchedule("This schedule is view only.");
return 0;
}
上面这段代码中,我们首先定义了Reminder、Encrypter和Storage三个子系统类,然后定义了一个ScheduleManagerFacade类作为外观类,客户端只需要和这个类打交道就可以了。ScheduleManagerFacade的每个成员函数都封装了子系统的实现细节,对外提供了统一的接口,可以方便地对日程进行创建、更新、删除和查看操作,不必去理解复杂的子系统实现。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通过C++程序示例理解设计模式中的外观模式 - Python技术站