本文来源于读者朋友提问,期望出一篇设计模式相关的文章。
关于设计模式,我看了很多书籍和视频,但由于部分设计模式并不常用,所以也难免有些遗忘。后来索性就用到哪个时再深入学习哪个。
那我是怎么学习设计模式的呢,我现在会花更多的时间和精力了解设计原则,毕竟李建忠老师曾讲过:了解设计原则远比知道23种设计模式更重要。
本文将在介绍设计原则的基础上,抛砖引玉,简述我常用的六种设计模式。
设计原则是架构设计的指导准则,也是我们学习设计模式的基础。八大设计原则如下:
接下来抛砖引玉,简单介绍下我常用的几种设计模式。
单例模式保证一个类只有一个实例的特性,适用于日志、公共数据等全局性质的对象。
适用场景:
优点:
缺点:
代码示例:
class Singleton {
private:
static Singleton* instance;
Singleton() {}
public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};
Singleton* Singleton::instance = nullptr;
工厂模式用于创建对象,尤其是同一类型对象的创建多使用工厂模式,如图形类(下含各种类型的图形)、数据库类(下含各种数据类型的数据库)等。
适用场景:
优点:
缺点:
代码示例:
class IProduct {
public:
virtual void use() = 0;
};
class ConcreteProductA :public IProduct {
public:
void use() override {
std::cout << "Using Product A" << std::endl;
}
};
class ConcreteProductB :public IProduct {
public:
void use() override {
std::cout << "Using Product B" << std::endl;
}
};
class Factory {
public:
static IProduct* createProduct(int type) {
if (type == 1) {
returnnew ConcreteProductA();
} elseif (type == 2) {
returnnew ConcreteProductB();
}
returnnullptr;
}
};
策略模式用于定义支持不同行为的相同方法,使得方法可以在不改变类的情况下改变行为。最常见的就是普通会员、VIP会员、SVIP会员的计费方法,我们可以使用策略模式来实现。
适用场景:
优点:
缺点:
代码示例:
class IStrategy {
public:
virtual double calculatePrice(double originalPrice) = 0;
};
class NormalStrategy :public IStrategy {
public:
double calculatePrice(double originalPrice) override {
return originalPrice;
}
};
class VIPStrategy :public IStrategy {
public:
double calculatePrice(double originalPrice) override {
return originalPrice * 0.8;
}
};
class SVIPStrategy :public IStrategy {
public:
double calculatePrice(double originalPrice) override {
return originalPrice * 0.5;
}
};
class Context {
private:
IStrategy* strategy;
public:
Context(IStrategy* s) : strategy(s) {}
double executeStrategy(double originalPrice) {
return strategy->calculatePrice(originalPrice);
}
};
模板模式定义了一个算法的骨架,而将一些步骤延迟到子类中。比如一个扬声器的实现类来讲,出声音具备相同的流程:初始化设备、播放。但是不同的扬声器的初始化设备的方法不同,我们可以使用模板模式来实现。
适用场景:
优点:
缺点:
代码示例:
class AbstractSpeaker {
public:
void play() {
initializeDevice();
openDevice();
doPlay();
closeDevice();
}
protected:
virtual void initializeDevice() = 0;
virtual void openDevice() {
std::cout << "Opening device" << std::endl;
}
virtual void doPlay() {
std::cout << "Playing" << std::endl;
}
virtual void closeDevice() {
std::cout << "Closing device" << std::endl;
}
};
class SpeakerA :public AbstractSpeaker {
protected:
void initializeDevice() override {
std::cout << "Initializing Speaker A" << std::endl;
}
};
class SpeakerB :public AbstractSpeaker {
protected:
void initializeDevice() override {
std::cout << "Initializing Speaker B" << std::endl;
}
};
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
适用场景:
优点:
缺点:
代码示例:
class IObserver {
public:
virtual void update() = 0;
};
class ISubject {
public:
virtual void attach(IObserver* observer) = 0;
virtual void detach(IObserver* observer) = 0;
virtual void notify() = 0;
};
class ConcreteSubject :public ISubject {
private:
std::vector<IObserver*> observers;
int state;
public:
void attach(IObserver* observer) override {
observers.push_back(observer);
}
void detach(IObserver* observer) override {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() override {
for (IObserver* observer : observers) {
observer->update();
}
}
void setState(int newState) {
state = newState;
notify();
}
};
class ConcreteObserver :public IObserver {
private:
ConcreteSubject* subject;
public:
ConcreteObserver(ConcreteSubject* subj) : subject(subj) {}
void update() override {
std::cout << "Observer updated: " << subject->getState() << std::endl;
}
};
适配器模式分为类适配器和对象适配器,主要用于接口的匹配。
适用场景:
优点:
缺点:
代码示例:
class ITarget {
public:
virtual ~ITarget() {}
virtual void request() = 0;
};
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee specific request" << std::endl;
}
};
class Adapter :public ITarget {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* adaptee) : adaptee(adaptee) {}
void request() override {
adaptee->specificRequest();
}
};
本文所述只是我常用的几种设计模式,也仅仅是抛砖引玉。但是设计原则是值得我们深入理解,并值得在工程中加以运用,熟能生巧。