這個問題發生是因為我們試圖在兩個獨立的維度上擴展形狀類別: 形狀和顏色。這是繼承中一個非常常見的問題
接下來,we can extract the color-related code into its own class with two subclasses: Red and Blue
The Shape class then gets a reference field pointing to one of the color objects
That reference will act as a bridge between the Shape and Color classes
結語
Abstraction: 定義抽象類的接口
RefinedAbstraction: 擴展Abstraction中的接口
Implementor: 定義實作類的接口
ConcreteImplementor: 實作Implementor接口
/**
* 實作(Implementation)定義了所有實作類別的接口
* 它不必與抽象(Abstraction)的接口相匹配。事實上,這兩個接口可以完全不同
* 通常,實作接口僅提供原始操作,而抽象則基於這些原始操作定義更高級的操作
*/
class Implementation {
virtual ~Implementation() {}
virtual std::string OperationImplementation() const = 0;
};
/**
* 每個具體實作(Concrete Implementation)對應於一個特定平台
* 並使用該平台的API實現實作接口
*/
class ConcreteImplementationA : public Implementation {
public:
std::string OperationImplementation() const override {
return "ConcreteImplementationA: Here's the result on the platform A.\n";
}
};
class ConcreteImplementationB : public Implementation {
public:
std::string OperationImplementation() const override {
return "ConcreteImplementationB: Here's the result on the platform B.\n";
}
};
/**
* 抽象(Abstraction)定義了兩個類別階層中"控制"部分的接口
* 它維護一個實作階層對象的引用,並將所有實際工作委派給這個對象
*/
class Abstraction {
protected:
Implementation* implementation_;
public:
Abstraction(Implementation* implementation) : implementation_(implementation) {
}
virtual ~Abstraction() {
}
virtual std::string Operation() const {
return "Abstraction: Base operation with:\n" +
this->implementation_->OperationImplementation();
}
};
/**
* 你可以擴展抽象,而不改變實作類別
*/
class ExtendedAbstraction : public Abstraction {
public:
ExtendedAbstraction(Implementation* implementation) : Abstraction(implementation) {
}
std::string Operation() const override {
return "ExtendedAbstraction: Extended operation with:\n" +
this->implementation_->OperationImplementation();
}
};
/**
* 除了初始化階段,其中一個抽象對象與特定實作對象相連接外
* 客戶端代碼應僅依賴於抽象類別。這樣,客戶端代碼可以支持任何抽象-實作組合
*/
void ClientCode(const Abstraction& abstraction) {
// ...
std::cout << abstraction.Operation();
// ...
}
/**
* 客戶端代碼應能夠與任何預配置的抽象-實作組合一起工作
*/
int main() {
Implementation* implementation = new ConcreteImplementationA;
Abstraction* abstraction = new Abstraction(implementation);
ClientCode(*abstraction);
std::cout << std::endl;
implementation = new ConcreteImplementationB;
abstraction = new ExtendedAbstraction(implementation);
ClientCode(*abstraction);
}
Output:
Abstraction: Base operation with:
ConcreteImplementationA: Here's the result on the platform A.
ExtendedAbstraction: Extended operation with:
ConcreteImplementationB: Here's the result on the platform B.