在策略模式(链接:策略模式)中,作为行为型设计模式,它根据外部传入实际对象来实现解耦和复用
实际对象的产生就引入了一种创建型设计模式 – 工厂方法模式
所谓创建型模式,就是避免在代码中对象创建(new)过程所导致的紧耦合(依赖具体类),从而在对象创建的代码中实现结构的稳定。
class Dianping {
public:
void review() {
Food *food = new ChinaFood; // ChinaFood是具体依赖类
Review reviewer(food);
reviewer.isYummy();
}
};
上面代码看似也没有问题,但是由于编译时依赖了ChinaFood
,违反了依赖倒置原则。
Food *makeFood(FoodType type) {
if (type == CHINA)
return new ChinaFood;
else if (type == JAPAN)
return new JapanFood;
else if (type == GERMANY)
return new GermenyFood;
}
class Dianping {
public:
void review() {
Food *food = makeFood(CHINA);
Review reviewer(food);
reviewer.isYummy();
}
};
在上面代码中,有些第三方库提供一个创建对象的接口,通过你的实际参数,去匹配一个对象用作返回,这样其实在代码中也没能实现松耦合。
Food *makeFood() {
return new ChinaFood;
}
class Dianping {
public:
void review() {
Food *food = makeFood();
Review reviewer(food);
reviewer.isYummy();
}
};
很多第三方类库里面有这样的设计,但是里面的具体对象很单一,只返回一个唯一确切的实现。但是这样的修改有所改善,至少从Dianping
这个类可以避免编译时依赖,从而实现松耦合。
这两种设计为松耦合提供了一个思路,就是能够通过同一个函数来创建不同的对象。我们使用基于对象的方式来对上面代码稍作修改:
class FoodFactory {
public:
Food *makeFood() { return new ChinaFood; }
};
class Dianping {
public:
void review() {
FoodFactory factory;
Food *food = factory.makeFood();
Review reviewer(food);
reviewer.isYummy();
}
};
然后采用面向对象的方法,并且将FoodFactory
作为成员,让makeFood
可以产生不同的Food:
// 首先将makeFood抽象化
class FoodFactory {
public:
virtual Food *makeFood() = 0;
};
// 其次增加FoodFactory *类型成员,并在任何时候(这里是构造阶段)绑定实际对象
class Dianping {
public:
Dianping(FoodFactory *_factory) : factory_{_factory} {}
void review() {
Food *food = this->factory_->makeFood();
Review reviewer(food);
reviewer.isYummy();
}
private:
FoodFactory *factory_;
};
这样一修改,事情变得有趣了起来,我们通过多态实现了通过同一个方法名,在运行时绑定不同的对象,因此我们又根据开闭原则,设计不同的实现,从而使得类Dianping
和类FoodFactory
都实现各自的解耦
class ChinaFoodFactory : public FoodFactory {
public:
~ChinaFoodFactory() override {}
Food *makeFood() { return ChinaFood; }
};
class JapanFoodFactory : public FoodFactory {
public:
~ChinaFoodFactory() override {}
Food *makeFood() { return JapanFood; }
};
class GermenyFactory : public FoodFactory {
public:
~ChinaFoodFactory() override {}
Food *makeFood() { return GermenyFood; }
};
松耦合并不是把依赖具体类(变化)消灭,而是把变化缩窄到一个可控的狭小的位子,让变化不充斥在代码的任何地方。
通过定义一个用于对象创建的接口,让其子类去决定具体实现化那个类