C++设计模式 实例(updating)

一、预热

  什么是设计模式:设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解并且保证代码可靠性。
  设计模式目标:可复用
  思维模式比代码技巧更重要,设计原则比模式更重要!

二、设计原则

  • 依赖倒置原则(DIP)
     稳定应该依赖于稳定,不能有对变化的依赖。对变化应该隔离开。
  • 开放封闭原则(OCP)
     对扩展开放,对更改封闭。类模块应该是可扩展的,但是不可修改。
  • 单一职责原则(SRP)
     一个类应该仅有一个引起它变化的原因,变化的方向隐含着类的责任。
  • 里氏代换原则 Liskov(LSP)
     子类必须能替换它们的基类(IS-A),继承表达类型抽象。
  • 接口隔离原则(ISP)
     接口应该小而完备。
  • 优先使用对象组合,而不是类继承
     继承在某种程度上破坏了封装性,子类父类耦合度高。但也不是说不能用继承,某些情况下可能继承更适合。
  • 封装变化点
     将稳定和变化的部分隔离开,出现变化时,稳定部分不需要改动。
  • 针对接口编程,而不是针对实现编程
     不将变量类型声明为某个特定的具体类,而是声明为某个接口。
     客户程序无需知道对象的具体类型,只需要知道对象所具有的接口。
     减少系统中各部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案。

三、GOF-23模式分类、重构

3.1 模式分类

  • 从目的来看:
  1. 创建型( Creational)模式: 将对象的部分创建工作延迟到类或者其他对象,从而应对需求变化为对象创建时具体类型现引来的冲击。
    包括:单例模式,简单工厂模式,抽象工厂模式,工厂方法模式,原型模式,建造者模式
  2. 结构型( Structural)模式: 通过类继承或者对象组合获得更活的结构,从而应对需求变化为对象的结构带来的冲击。
    包括:适配器模式,桥接模式,组合模式,装饰模式,外观模式,享元模式,代理模式
  3. 行为型( Behavioral)模式: 通过类继承或者对象组合来划类与对象间的职责,从而应对需求变化为多个交互的对象带的冲击。
    包括:职责链模式,命令模式,解释器模式,迭代器模式,中介者模式,备忘录模式,观察者模式,状态模式,策略模式,模板方法模式,访问者模式
  • 从范围来看:
  1. 类模式处理类与子类的静态关系。
  2. 对象模式处理对象间的动态关系。

3.2 重构关键技法

  • 静态 —> 动态
  • 早绑定 —> 晚绑定
  • 继承 —> 组合
  • 编译时依赖 —> 运行时依赖
  • 紧耦合 —> 松耦合

四、TemplateMethod Mode 模板方法模式

  定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(晚绑定)到子类中。 Template ethod使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤

在这里插入图片描述
  模板方法实现了一个算法的框架,有些步骤可能是固定不变的,不需要暴露给用户,而有些步骤是允许用户重写的,这些步骤会被封装成一个或多个方法,以虚函数的形式提供给用户,允许用户自己实现。
  在下面的代码中,抽象基类的TemplateMethod方法中可能还有其它的步骤,不止这两个。用户只需要根据实际情况重写这些接口即可,不用关心整体的工作流程。(稳定的框架为非虚方法,可变化的步骤为虚方法)

#include <iostream>

using namespace::std;

class AbstractClass
{
   
public:
	void TemplateMethod() {
   
		CustomOperation1();
		CustomOperation2();
	}
protected:
	//抽象基类定义的默认Operation
	virtual void CustomOperation1() {
   
		cout << "Default Operation1." << endl;
	}
	virtual void CustomOperation2() {
   
		cout << "Default Operation2." << endl;
	}
};

class ConcreteClassA : public AbstractClass
{
   
public:
	//具体类重写的Operation
	virtual void CustomOperation1() {
   
		cout << "ConcreteA Operation1." << endl;
	}
	virtual void CustomOperation2() {
   
		cout << "ConcreteA Operation2." << endl;
	}
};

class ConcreteClassB : public AbstractClass
{
   
public:
	//具体类重写的Operation
	virtual void CustomOperation1() {
   
		cout << "ConcreteB Operation1." << endl;
	}
	virtual void CustomOperation2() {
   
		cout << "ConcreteB Operation2." << endl;
	}
};


int main(void)
{
   
	AbstractClass * pAbstract = new AbstractClass();
	pAbstract->TemplateMethod();

	AbstractClass * pConcreteA = new ConcreteClassA();
	pConcreteA->TemplateMethod();

	AbstractClass * pConcreteB = new ConcreteClassB();
	pConcreteB->TemplateMethod();

	return 0;
}

五、Strategy Mode 策略模式

  开放封闭原则

  定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。该模式使得算法可独立于使用它的客户而变化。

在这里插入图片描述
  策略模式其实是对算法的封装,当处理一个问题可能有多种算法(方法)时就可以使用该模式。Strategy类就是对该算法的封装,具体类则是对该算法的不同实现。
  当程序中出现if…else…或者switch…case…,而且很有可能会增加分支时,一般就要策略模式了。

#include <iostream>
#include <string>

using namespace std;

class Strategy
{
   
public:
	virtual ~Strategy() {
    }
	virtual void AlgorithmInterface() = 0;
};

//ConcreteStrategyA、ConcreteStrategyB对同一个算法的接口做了不同的实现
class ConcreteStrategyA : public Strategy
{
   
public:
	virtual void AlgorithmInterface()
	{
   
		cout << "AlgorithmInterface Implemented by ConcreteStrategyA." << endl;
	}
};

class ConcreteStrategyB : public Strategy
{
   
public:
	virtual void AlgorithmInterface()
	{
   
		cout << "AlgorithmInterface Implemented by ConcreteStrategyB." << endl;
	}
};

//Context代表上下文
class Context
{
   
public:
	~Context()
	{
   
		delete m_Strategy;
	}

	Context(Strategy * pStrategy) : m_Strategy
### C++控制台游戏开发中实现输出与数据分离的最佳实践 在C++控制台游戏开发中,为了实现输出与数据的分离,可以采用MVC(模型-视图-控制器)模式或观察者模式。这两种模式都能有效地解耦系统的不同组件,从而提高代码的可维护性和扩展性。 #### 使用MVC模式实现输出与数据分离 MVC是一种常见的软件架构模式,它将应用程序划分为三个主要部分:模型(Model)、视图(View)和控制器(Controller)。 - **模型(Model)** 负责管理应用的数据逻辑以及业务规则。在游戏中,这可能包括游戏角色的状态、得分或其他动态变化的信息[^1]。 - **视图(View)** 是用户界面的一部分,负责向用户展示数据并接收用户的输入。对于控制台游戏来说,视图可能是简单的字符界面,用于显示游戏状态给玩家。 - **控制器(Controller)** 处理来自用户的输入并将这些输入转换成命令传递给模型或视图。例如,在游戏中,当玩家按下某个键时,控制器会更新角色的位置或者触发特定的游戏事件。 以下是基于MVC模式的一个简单示例: ```cpp // Model (Game Data) class GameData { public: int score; std::string playerStatus; void updateScore(int points) { score += points; } }; // View (Output to Console) class GameView { public: void display(const GameData& data) { std::cout << "Player Status: " << data.playerStatus << "\n"; std::cout << "Current Score: " << data.score << "\n"; } }; // Controller (Handles Input and Updates Model/View) class GameController { private: GameData model; GameView view; public: void handleInput(char input) { switch (input) { case 'a': model.updateScore(-10); break; case 'd': model.updateScore(+10); break; default: break; } // Update the view with new game state view.display(model); } }; ``` 通过这种方式,我们可以清晰地区分数据处理、用户交互和数据显示的功能模块。 --- #### 使用观察者模式实现输出与数据分离 观察者模式适用于需要在一个对象改变其状态时自动通知其他依赖该对象的对象的情况。这种模式非常适合于那些希望保持松散耦合的设计场景。 在C++中实现观察者模式通常涉及定义两个核心概念——`Subject` 和 `Watcher`。其中,`Subject` 表示被观察的主题,而 `Watcher` 则表示具体的观察者实例[^2]。下面是一个简化版本的例子来说明如何利用此模式构建一个响应式的游戏框架: ```cpp #include <iostream> #include <vector> // Abstract Observer Interface #pragma once class Watcher { public: virtual ~Watcher() {} virtual void notify(int value) = 0; // Pure Virtual Function for Notification Handling }; // Concrete Subject Class class GameEngine : public Watcher { private: std::vector<Watcher*> observers; int gameStateValue; public: void attach(Watcher* observer) { observers.push_back(observer); } void detach(Watcher* observer) { auto it = std::find(observers.begin(), observers.end(), observer); if (it != observers.end()) { observers.erase(it); } } void setGameState(int newValue) { this->gameStateValue = newValue; notifyObservers(); } protected: void notifyObservers() const { for(auto obs : observers){ obs->notify(gameStateValue); } } }; // Example of a concrete watcher that reacts based on notifications from subject. class PlayerUIUpdater : public Watcher { public: void notify(int value) override { std::cout << "Updating UI... New Value Received:" << value << '\n'; } }; int main(){ GameEngine engine; PlayerUIUpdater uiUpdater; engine.attach(&uiUpdater); // Simulate some changes in game state values... engine.setGameState(5); // This will trigger notification mechanism. return 0; } ``` 上述代码展示了如何创建一个基础的通知机制,使得每当游戏引擎中的某些条件发生变化时,所有注册过的观察者都会得到及时的通知,并作出相应的反应[^3]。 --- #### 总结 无论是选择MVC还是观察者模式,都能够在一定程度上帮助开发者更好地组织他们的项目结构,使程序更加灵活易懂。然而需要注意的是,每种设计都有各自的适用范围和局限之处;因此实际操作过程中还需要根据具体情况做出合理的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值