一. 状态模式
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
应用场景:
- 如果对象需要根据自己当前状态进行不同行为,同时状态的数量非常多且与状态相关的代码会频繁变更的话,可使用状态模式
- 如果某个类需要根据成员变量的当前值改变自身行为,从而需要使用大量的条件语句时,可使用该模式
- 当相似状态和基于条件的状态机转换中存在许多重复代码时,可使用状态模式
我们来模拟一个例子:水在不同温度下,表现出不同的状态,固态、液态和气态
#include <cstdio>
#include <memory>
class State{
public:
virtual ~State() = default;
public:
virtual void showState(void) = 0;
};
class Gas : public State{
public:
void showState(void) override{
printf("Gas\n");
}
};
class Solid : public State{
public:
void showState(void) override{
printf("Solid\n");
}
};
class Liquid : public State{
public:
void showState(void) override{
printf("Liquid\n");
}
};
class Water{
private:
std::unique_ptr<State> state;
int temperature;
public:
Water()
:state(std::make_unique<Liquid>()), temperature(25){}
public:
void showState(void){
printf("%d degree Celsius, ", this->temperature);
this->state->showState();
}
void setTemperature(int temperature){
this->temperature = temperature;
if(temperature <= 0)
this->state = std::make_unique<Solid>();
else if(temperature <= 100)
this->state = std::make_unique<Liquid>();
else
this->state = std::make_unique<Gas>();
}
};
int main(void){
Water water;
water.showState();
water.setTemperature(0);
water.showState();
water.setTemperature(101);
water.showState();
return 0;
}
状态模式与状态机的概念紧密相关。状态模式与策略模式相似,但他们有一个关键性的不同:在状态模式中,特定状态知道其它所有状态的存在,且能触发从一个状态到另一个状态的转换;策略模式则完全不知道其它策略的存在
二. 适配器模式
适配器模式:将一个类的接口转换成客户希望的另一个接口,使得原本接口不兼容而不能一起工作的那些类可以一起工作
应用场景:当你希望使用某个类,但是其接口与其它代码不兼容时,可以使用适配器模式
我们来模拟一个例子:中国插排和英国插排并不相同,但通过转接器就可以使用英国插排为依赖中国插排的电器充电
#include <cstdio>
#include <string>
class Socket{
private:
int pin_num;
std::string pin_shape;
public:
Socket(int pin_num, const std::string &pin_shape)
:pin_num(pin_num), pin_shape(pin_shape){}
virtual ~Socket() = default;
public:
int getPinNum(void) const{
return this->pin_num;
}
std::string getPinShape(void) const{
return this->pin_shape;
}
};
class BritishSocket : public Socket{
public:
BritishSocket()
:Socket(3, "T-shaped square"){}
};
class Adapt{
public:
Socket adapt(const BritishSocket &british_socket){
return Socket(3, "Figure-eight flat");
}
};
class Computer{
public:
void Charging(const Socket &socket){
if(socket.getPinNum() == 3 && socket.getPinShape() == "Figure-eight flat")
printf("Charging successful.\n");
else
printf("The socket doesn't match.\n");
}
};
int main(void){
BritishSocket british_socket;
Computer my_computer;
my_computer.Charging(british_socket);
Adapt apt;
my_computer.Charging(apt.adapt(british_socket));
return 0;
}
作业
对于 x 的某个给定值,求出一个多项式在 x 的值,也可以形式化为一种累积。假定需要求下面多项式的值: $$a_n x^n+a_{n-1}x^{n-1}+\dots+a_1 x+a_0$$ 采用著名的 Horner 规则,可以构造出下面的计算:$$(\dots(a_n x+a_{n-1}) x+\dots+a_1) x+a_0$$ 利用 Horner 规则求多项式的值,假定多项式的系数安排在一个 vector 里