创建型模式提供了创建对象的机制,旨在提升已有代码的灵活性和可复用性。
部分插图来自: https://refactoringguru.cn/design-patterns/catalog
简单工厂模式严格来说并不是一种设计模式,而更像是一种编程习惯。简单工厂模式在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来提供新创建的对象。当这个提供对象接口被定义为静态方法时,简单工厂模式也被称为静态工厂模式。
简单工厂模式包含如下角色:
简单工厂模式优点:
简单工厂模式缺点:增加新产品时需要修改工厂类的代码,违背了开闭原则(对扩展开放,对修改封闭)。
#include
/* 猫基类 */
class Cat {
public:
virtual void bark() = 0;
virtual ~Cat() = default;
};
/* 狸花猫 */
class DragonLi : public Cat {
public:
void bark() override {
std::cout << "DragonLi: meow~" << std::endl;
}
};
/* 缅因猫 */
class MaineCoon : public Cat {
public:
void bark() override {
std::cout << "MaineCoon: meow~" << std::endl;
}
};
/* 布偶猫 */
class Ragdoll : public Cat {
public:
void bark() override {
std::cout << "Ragdoll: meow~" << std::endl;
}
};
/* 静态工厂类 专门用来生产猫咪 */
class SimpleCatFactory {
public:
static Cat *CreateCat(const std::string &category) {
if (category == "DragonLi") {
return new DragonLi();
} else if (category == "MaineCoon") {
return new MaineCoon();
} else {
return new Ragdoll();
}
}
};
int main() {
Cat *dragonLi = SimpleCatFactory::CreateCat("DragonLi");
dragonLi->bark();
Cat *maineCoon = SimpleCatFactory::CreateCat("MaineCoon");
maineCoon->bark();
Cat *ragdoll = SimpleCatFactory::CreateCat("Ragdoll");
ragdoll->bark();
delete dragonLi;
delete maineCoon;
delete ragdoll;
return 0;
}
atreus@MacBook-Pro % clang++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
DragonLi: meow~
MaineCoon: meow~
Ragdoll: meow~
atreus@MacBook-Pro %
工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法接口, 允许子类决定所要实例化对象的类型。工厂方法模式使一个产品类的实例化延迟到工厂的子类中进行。
工厂方法模式包含如下角色:
工厂方法模式优点:
工厂方法模式缺点:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,增加了系统的复杂度。
#include
/* 猫基类 */
class Cat {
public:
virtual void bark() = 0;
virtual ~Cat() = default;
};
/* 狸花猫 */
class DragonLi : public Cat {
public:
void bark() override {
std::cout << "DragonLi: meow~" << std::endl;
}
};
/* 缅因猫 */
class MaineCoon : public Cat {
public:
void bark() override {
std::cout << "MaineCoon: meow~" << std::endl;
}
};
/* 抽象工厂类 */
class CatFactory {
public:
virtual Cat *CreateCat() = 0;
virtual ~CatFactory() = default;
};
class DragonLiFactory : public CatFactory {
public:
Cat *CreateCat() override {
return new DragonLi();
}
};
class MaineCoonFactory : public CatFactory {
public:
Cat *CreateCat() override {
return new MaineCoon();
}
};
int main() {
CatFactory *dragonLiFactory = new DragonLiFactory();
Cat *dragonLi = dragonLiFactory->CreateCat();
dragonLi->bark();
delete dragonLi;
delete dragonLiFactory;
CatFactory *maineCoonFactory = new MaineCoonFactory();
Cat *maineCoon = maineCoonFactory->CreateCat();
maineCoon->bark();
delete maineCoon;
delete maineCoonFactory;
return 0;
}
atreus@MacBook-Pro % clang++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
DragonLi: meow~
MaineCoon: meow~
atreus@MacBook-Pro %
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产某个单一的产品,而抽象工厂模式可生产一系列相关的产品。
抽象工厂模式包含如下角色:
抽象工厂方法模式优点:
抽象工厂方法模式缺点:代码较为复杂,当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。比如我们在下面代码中添加一个有关驱逐舰的方法,包括抽象工厂在内的工厂类都需要进行修改。
#include
/* 战列舰基类 */
class Battleship {
public:
virtual void fire() = 0;
virtual ~Battleship() = default;
};
/* 巡洋舰基类 */
class Cruiser {
public:
virtual void fire() = 0;
virtual ~Cruiser() = default;
};
/* 抽象工厂类 */
class AbstractFactory {
public:
virtual Battleship *createBattleship() = 0;
virtual Cruiser *createCruiser() = 0;
virtual ~AbstractFactory() = default;
};
/* 衣阿华级战列舰 美国 */
class Iowa : public Battleship {
public:
void fire() override {
std::cout << "Iowa: fire!" << std::endl;
}
};
/* 得梅因级巡洋舰 美国 */
class DesMoines : public Cruiser {
public:
void fire() override {
std::cout << "DesMoines: fire!" << std::endl;
}
};
/* 大和级战列舰 日本 */
class Yamato : public Battleship {
public:
void fire() override {
std::cout << "Yamato: fire!" << std::endl;
}
};
/* 伊吹级巡洋舰 日本 */
class Ibuki : public Cruiser {
public:
void fire() override {
std::cout << "Ibuki: fire!" << std::endl;
}
};
/* 美国工厂类 */
class AmericanFactory : public AbstractFactory {
public:
Battleship *createBattleship() override {
return new Iowa;
}
Cruiser *createCruiser() override {
return new DesMoines;
}
};
/* 日本工厂类 */
class JapaneseFactory : public AbstractFactory {
public:
Battleship *createBattleship() override {
return new Yamato;
}
Cruiser *createCruiser() override {
return new Ibuki;
}
};
int main() {
AbstractFactory *americanFactory = new AmericanFactory;
Battleship *iowa = americanFactory->createBattleship();
iowa->fire();
delete iowa;
delete americanFactory;
AbstractFactory *japaneseFactory = new JapaneseFactory;
Cruiser *ibuki = japaneseFactory->createCruiser();
ibuki->fire();
delete ibuki;
delete japaneseFactory;
return 0;
}
atreus@MacBook-Pro % clang++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
Iowa: fire!
Ibuki: fire!
atreus@MacBook-Pro %
原型模式是一种创建型设计模式, 它用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象, 而又无需使代码依赖它们所属的类(依赖实例化后的对象,不依赖类定义)。
原型模式包含如下角色:
clone()
方法。clone()
方法,它是可被复制的对象。clone()
方法来复制新的对象。原型模式优点:
原型模式缺点:克隆包含循环引用的复杂对象可能会非常麻烦。
#include
/* 抽象原型类 */
class Prototype {
public:
virtual Prototype *clone() = 0;
virtual ~Prototype() = default;
};
/* 猫咪类 */
class Cat : public Prototype {
public:
Cat() = default;
/* 深拷贝 */
Cat *clone() override {
return new Cat();
}
/* 浅拷贝 */
// Cat *clone() override {
// return this;
// }
};
int main() {
Cat *oldCat = new Cat();
Cat *newCat = oldCat->clone();
std::cout << oldCat << std::endl;
std::cout << newCat << std::endl;
delete oldCat;
delete newCat;
return 0;
}
atreus@MacBook-Pro % clang++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
0x60000321c040
0x60000321c050
atreus@MacBook-Pro %
生成器模式将一个复杂对象的构建与表示分离,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
建造者模式包含如下角色:
建造者模式的优点:
建造者模式的缺点:
#include
#include
using namespace std;
/* 产品类 */
class Cat {
private:
string m_leg; // 腿
string m_tail; // 尾巴
public:
const string &getLeg() const {
return m_leg;
}
void setLeg(const string &leg) {
m_leg = leg;
}
const string &getTail() const {
return m_tail;
}
void setTail(const string &tail) {
m_tail = tail;
}
};
/* 抽象建造者 */
class Builder {
protected:
Cat *m_cat = new Cat();
public:
virtual void buildLeg() = 0;
virtual void buildTail() = 0;
virtual Cat *createCat() = 0;
virtual ~Builder() {
delete m_cat;
}
};
/* 具体构建者 */
class DragonLiBuilder : public Builder {
public:
void buildLeg() override {
m_cat->setLeg("狸");
}
void buildTail() override {
m_cat->setTail("花");
}
Cat *createCat() override {
return m_cat;
}
};
/* 具体构建者 */
class RagdollBuilder : public Builder {
public:
void buildLeg() override {
m_cat->setLeg("布");
}
void buildTail() override {
m_cat->setTail("偶");
}
Cat *createCat() override {
return m_cat;
}
};
/* 指挥者 */
class Director {
private:
Builder *m_builder;
public:
explicit Director(Builder *builder) {
m_builder = builder;
}
Cat *construct() {
m_builder->buildLeg();
m_builder->buildTail();
return m_builder->createCat();
}
~Director() {
delete m_builder;
}
};
int main() {
Director dragonLiDirector(new DragonLiBuilder);
Cat *dragonLi = dragonLiDirector.construct();
cout << dragonLi->getLeg() << dragonLi->getTail() << endl;
Director ragdollDirector(new RagdollBuilder);
Cat *ragdoll = ragdollDirector.construct();
cout << ragdoll->getLeg() << ragdoll->getTail() << endl;
return 0;
}
atreus@MacBook-Pro % clang++ main.cpp -o main -std=c++11
atreus@MacBook-Pro % ./main
狸花
布偶
atreus@MacBook-Pro %