本文通過運用設計模式比沒用設計模式的優勢在哪?
設計模式主要是要抓住穩定部分和易變部分,文章結尾會指出。
還指出工廠方法被設計出來,最開始想要解決的問題是什麼。
#include <iostream>
using namespace std;
//老代碼
class Fruit {
public:
virtual void eaten() = 0;
virtual ~Fruit() {}
};
class Apple : public Fruit {
public:
void eaten() override {
cout << "eat apple" << endl;
}
};
class Orange : public Fruit {
public:
void eaten() override {
cout << "eat orange" << endl;
}
};
class Banana: public Fruit {
public:
void eaten() override {
cout << "eat banana" << endl;
}
};
//老代碼
class Man {
public:
void eat() {
Fruit *fruit = new Apple; //這裏違背了"不與陌生人交流的原則"
fruit->eaten();
delete(fruit);
}
};
//需求改變,Man可以喫任意的水果。注意fruit被喫掉後,需要在eat中析構。
//新增枚舉,修改Man::eat方法
//這種方法違背開閉原則,如果在添加水果種類,還要修改FruitType和Man2類。
enum FruitType {
APPLE,
ORANGE,
BANANA
};
class Man2 {
public:
void eat(FruitType type) {
Fruit *fruit = nullptr;
switch (type) {
case APPLE:
fruit = new Apple;
break;
case ORANGE:
fruit = new Orange;
break;
case BANANA:
fruit = new Banana;
break;
}
fruit->eaten();
delete(fruit);
}
};
//工廠方法
//抽象工廠
//將來在新增水果類只需要增加對應的工廠方法。
class FruitFactory {
public:
virtual Fruit* creatFruit() = 0;
virtual ~FruitFactory() {}
};
class AppleFactory : public FruitFactory {
public:
Fruit* creatFruit() override {
return new Apple;
}
};
class OrangeFactory : public FruitFactory {
public:
Fruit* creatFruit() override {
return new Orange;
}
};
class BananaFactory : public FruitFactory {
public:
Fruit* creatFruit() override {
return new Banana;
}
};
class Man3 {
public:
void eat(FruitFactory *factory) {
Fruit *fruit = factory->creatFruit();
fruit->eaten();
delete(fruit);
}
};
int main()
{
Man().eat();
Man2().eat(BANANA);
FruitFactory *factory = new OrangeFactory;
Man3().eat(factory);
delete(factory);
return 0;
}
工廠方法穩定部分:Fruit/FruitFactory
類,易變部分是:它們的子類。
策略方法讓Fruit
類解耦,但是又new
的存在還是要改變Man::eat
函數,工廠方法最開始是爲了解決new
帶來的問題。