当前位置: 首页 > news >正文

北京网站建设华网天下定制中国搜索

北京网站建设华网天下定制,中国搜索,手机公司网站建设,wordpress tipton引入:以一个对数组的增删改查为例。通过命令模式可以对数组进行增删改查以及撤销回滚。 一、基本概念 命令模式有多种分法,在本文中主要分为CommandMgr、Command、Receiver. CommandMgr主要用于控制命令执行等操作、Command为具体的命令、Receiver为命…

引入:以一个对数组的增删改查为例。通过命令模式可以对数组进行增删改查以及撤销回滚。

一、基本概念

命令模式有多种分法,在本文中主要分为CommandMgr、Command、Receiver.

CommandMgr主要用于控制命令执行等操作、Command为具体的命令、Receiver为命令具体要操作的对象。

总而言之,增删改查就是具体的Command、Receiver就是数组、CommandMgr负责控制命令的执行与回滚等。

二、程序设计

以下代码可从github下载:GitHub - laizilianglaiziliang/LearnCommandProject

1.Receiver
//"Receiver_Array.h"
#pragma once
#include<vector>
#include<optional>
#include<iostream>
template <class T>
class Receiver_Array
{
private:std::vector<T>* myArry;
public:~Receiver_Array(){}Receiver_Array() {myArry = new std::vector<T>();}Receiver_Array(std::vector<T>* _myArry){if (_myArry){myArry = new std::vector<T>(*_myArry);}else{myArry = new std::vector<T>();}}bool add(const int pos, const T& val){if (errorCheck(pos)){return false;}myArry->insert(pos + myArry->begin(), val);return true;}bool del(const int pos){if (errorCheck(pos)){return false;}myArry->erase(pos + myArry->begin());return true;}bool modify(const int pos, const T& val){if (errorCheck(pos)){return false;}myArry->erase(pos + myArry->begin());return true;}std::optional<T> seek(const int pos){if (errorCheck(pos)){return std::nullopt;}return (*myArry)[pos];}bool errorCheck(const int pos){if (pos >= myArry->size()){printf("  Operation Failed.Array Bounds Errors.  ");return true;}return false;}void display(){for (int i = 0; i < myArry->size(); ++i){std::cout << (*myArry)[i] << "  ";}std::cout << std::endl;}
};

在本例子中Receiver_Array类是一个模板类,可支持不同类型的数组。同时实现了对数组进行增删改查,为不同的命令类提供了基础的功能。

2.Command
//Command.h
#pragma once
#include "Receiver_Array.h"
#include<optional>
#include <memory>
class Command
{
public:		int m_iPos;bool m_bCanRevert;
public:Command(int _pos) : m_iPos(_pos), m_bCanRevert(true){}virtual ~Command(){}virtual bool  execute() = 0;virtual void* executeOther(){return nullptr;}virtual bool  undo() = 0;virtual bool  redo() = 0;
};
template <class T>
class AddCommand:public Command
{
private:std::shared_ptr<Receiver_Array<T>> m_Receiver_Array;T m_Val;
public:AddCommand() {}AddCommand(std::shared_ptr<Receiver_Array<T>> _receiver_Array, int _pos,const T& _val) :Command( _pos), m_Receiver_Array(_receiver_Array), m_Val(_val){		}virtual ~AddCommand() {//if (m_Receiver_Array)//{//	m_Receiver_Array->destory();//	m_Receiver_Array = nullptr;//}}bool execute() override{try{if (this->m_Receiver_Array->add(this->m_iPos, m_Val)){printf("  Add Success.");return true;}printf("  Add Fail.");return false;}catch(...){printf("  Add Fail.");return false;}return true; }virtual bool undo() override{try{if (this->m_Receiver_Array->del(this->m_iPos)){printf("  Undo Success.");return true;}}catch (...){}printf("  Undo Fail.");return false;}virtual bool redo() override{if (execute()){printf("  Redo Success.");return true;}printf("  Redo Fail.");return false;}
};
template <class T>
class DelCommand :public Command
{
private:std::shared_ptr<Receiver_Array<T>>  m_Receiver_Array;T m_Val;
public:DelCommand() {}DelCommand(std::shared_ptr<Receiver_Array<T>>  _receiver_Array, int _pos) :Command(_pos), m_Receiver_Array(_receiver_Array){}virtual ~DelCommand(){//if (m_Receiver_Array)//{//	m_Receiver_Array->destory();//	m_Receiver_Array = nullptr;//}}bool execute() override{try{std::optional<T> val = m_Receiver_Array->seek(m_iPos);if (val!=std::nullopt && this->m_Receiver_Array->del(this->m_iPos)){printf("  Del Success.");m_Val = val.value();return true;}printf("  Del Fail.");return false;}catch (...){printf("  Del Fail.");return false;}return true;}virtual bool undo() override{try{if (this->m_Receiver_Array->add(this->m_iPos, m_Val)){printf("  Undo Success.");return true;}}catch (...){}printf("  Undo Fail.");return false;}virtual bool redo() override{if (execute()){printf("  Redo Success.");return true;}printf("  Redo Fail.");return false;}
};
template <class T>
class ModifyCommand :public Command
{
private:std::shared_ptr<Receiver_Array<T>>  m_Receiver_Array;T m_Val;
public:ModifyCommand() {}ModifyCommand(std::shared_ptr<Receiver_Array<T>>  _receiver_Array, int _pos,const T& _val) :Command(_pos), m_Receiver_Array(_receiver_Array), m_Val(_val){}virtual ~ModifyCommand(){//if (m_Receiver_Array)//{//	m_Receiver_Array->destory();//	m_Receiver_Array = nullptr;//}}bool execute() override{try{std::optional<T> val = this->m_Receiver_Array->seek(m_iPos);//判断m_iPos是合法的if (val != std::nullopt && this->m_Receiver_Array->modify(this->m_iPos, m_Val)){printf("  Modify Success.");m_Val = val.has_value();//用于undo redoreturn true;}			printf("  Modify Fail.");return false;}catch (...){printf("  Modify Fail.");return false;}return true;}virtual bool undo() override{try{if (execute()){printf("  Undo Success.");return true;}}catch (...){}printf("  Undo Fail.");return false;}virtual bool redo() override{if (execute()){printf("  Redo Success.");return true;}printf("  Redo Fail.");return false;}
};
template <class T>
class SeekCommand :public Command
{
private:std::shared_ptr<Receiver_Array<T>>  m_Receiver_Array;
public:SeekCommand():m_bCanRevert(false) {}SeekCommand(std::shared_ptr<Receiver_Array<T>>  _receiver_Array, int _pos) :Command(_pos), m_Receiver_Array(_receiver_Array){m_bCanRevert = false;//, m_bCanRevert(false)}virtual ~SeekCommand(){//if (m_Receiver_Array)//{//	m_Receiver_Array->destory();//	m_Receiver_Array = nullptr;//}}bool execute() override{return false;}virtual void* executeOther() override{try{std::optional<T> val = m_Receiver_Array->seek(m_iPos);if (val == std::nullopt){printf("  Seek Fail.");return nullptr;}printf("  Seek Success.");T* ret = new T();*ret = val.value();return ret;}catch (...){}printf("  Seek Fail.");return nullptr;}virtual bool undo() override{printf("  Undo Fail.");return false;}virtual bool redo() override{printf("  Redo Fail.");return false;}
};

1)Command类是命令基类。本来也想将Command设计成模板类,但是后面想想感觉不太好,因为Command设计成模板类会影响到CommandMgr也变成模板类。如果Command类是模板类,要注意其属性如果在派生类中要用的话要用this指针去访问,否则会出现找不到标识符的问题。

可参考:

C++模板类中,派生类使用基类中数据或方法报“找不到标识符”_c++头文件引用其他类提示找不到符号-CSDN博客

2)Command类中有个m_bCanRevert属性用于判断该命令是否可以被撤销回滚,因为并不是所有的命令都支持撤销回滚,比如例子中的SeekCommand。

3)Command类中有个executeOther,因为SeekCommand执行后需要返回一个值,是特殊的命令,因此executeOther用于执行特殊的命令

4)其他的Command派生类依赖于Receiver_Array类,可能会出现多个类依赖于同一个Receiver_Array类对象的情况,因此把Receiver_Array类成员变量设置为智能指针方便内存的释放

5)其他的主要就是实现每个Command类的execute、undo、redo方法,这个直接看逻辑就能理解。

3.CommandMgr
//CommandMgr.h
#pragma once
#include <stack>
#include <memory>
class Command;
class CommandMgr
{
private:std::stack<std::shared_ptr<Command>> m_stkUndo;//undo栈std::stack<std::shared_ptr<Command>> m_stkRedo;//redo栈
public:CommandMgr();~CommandMgr();void execute(std::shared_ptr<Command> command) noexcept;void* executeOther(std::shared_ptr<Command> command)noexcept;void undo() noexcept;void redo() noexcept;
};
//CommandMgr.cpp
#include "CommandMgr.h"
#include "Command.h"
CommandMgr::CommandMgr()
{
}
CommandMgr::~CommandMgr()
{while (!m_stkRedo.empty()){m_stkRedo.pop();}while (!m_stkUndo.empty()){		m_stkUndo.pop();}
}
void CommandMgr::execute(std::shared_ptr<Command> command) noexcept
{if (command->execute()){printf("  Command Execute Success\n\n");if (command->m_bCanRevert){m_stkUndo.push(command);}}else{printf("  Command Execute Fail\n\n");}
}void* CommandMgr::executeOther(std::shared_ptr<Command> command) noexcept
{void* val = command->executeOther();if (val){printf("  Command Execute Success\n\n");if (command->m_bCanRevert){m_stkUndo.push(command);}return val;}else{printf("  Command Execute Fail\n\n");}return nullptr;
}void CommandMgr::undo() noexcept
{if (m_stkUndo.empty()){return;}std::shared_ptr<Command> command = m_stkUndo.top();if (command && command->m_bCanRevert && command->undo()){		m_stkUndo.pop();m_stkRedo.push(command);printf("  Command Undo Success\n\n");}else{printf("  Command Undo Fail\n\n");}
}void CommandMgr::redo() noexcept
{if (m_stkRedo.empty()){return;}std::shared_ptr<Command> command = m_stkRedo.top();if (command && command->m_bCanRevert && command->redo()){m_stkUndo.push(command);printf("  Command Redo Success\n\n");}else{printf("  Command Redo Fail\n\n");}
}

1)CommandMgr主要用于管理命令,用来操作具体的命令的调用控制、undo、redo控制。

2)因为Command类型对象的内存不太好管理,因此也使用了智能指针。

3)里面的undo、redo主要通过栈来实现。当命令execute过后便会添加到undo栈,接下来的undo、redo主要就是对undo栈和redo栈进行互相倒腾。

4.main函数

当做完上面的工作就能对数组进行方便的增删改查了,还可以撤销回退哦。

// LearnCommandProject.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。#include <iostream>
#include <vector>
#include "Command.h"
#include "Receiver_Array.h"
#include "CommandMgr.h"
#include <memory>
int main()
{std::vector<int> vec{ 1,2,3 };std::shared_ptr<Receiver_Array<int>> receiver_Array(new Receiver_Array<int>(&vec));std::shared_ptr<AddCommand<int>> addCommand(new AddCommand<int>(receiver_Array, 3, 4));CommandMgr commandMgr;commandMgr.execute(addCommand);commandMgr.undo();commandMgr.redo();receiver_Array->display();std::shared_ptr<SeekCommand<int>> seekCommand(new SeekCommand<int>(receiver_Array, 1));int* val= (int*)(commandMgr.executeOther(seekCommand));receiver_Array->display();delete val;val = nullptr;std::shared_ptr<DelCommand<int>> delCommand(new DelCommand(receiver_Array, 1));commandMgr.execute(delCommand);commandMgr.undo();commandMgr.redo();receiver_Array->display();std::shared_ptr<ModifyCommand<int>> modifyCommand(new ModifyCommand(receiver_Array, 2, 2));commandMgr.execute(modifyCommand);commandMgr.undo();commandMgr.redo();receiver_Array->display();printf("ok");
}

.上面的代码可能还有设计不好的地方,欢迎批评指正。


文章转载自:
http://dinncoupstream.stkw.cn
http://dinncowattlebird.stkw.cn
http://dinncosarcophagic.stkw.cn
http://dinncoradioteletype.stkw.cn
http://dinncogasteropod.stkw.cn
http://dinncohummel.stkw.cn
http://dinnconosegay.stkw.cn
http://dinncohypercorrect.stkw.cn
http://dinncofillet.stkw.cn
http://dinncocottonweed.stkw.cn
http://dinncoasepticize.stkw.cn
http://dinncoanopsia.stkw.cn
http://dinncodalmatian.stkw.cn
http://dinncorabic.stkw.cn
http://dinncotrick.stkw.cn
http://dinncojillaroo.stkw.cn
http://dinncosaker.stkw.cn
http://dinncononeffective.stkw.cn
http://dinncologicals.stkw.cn
http://dinncomigrator.stkw.cn
http://dinncocoastel.stkw.cn
http://dinncospinigrade.stkw.cn
http://dinncosavings.stkw.cn
http://dinncospanaemia.stkw.cn
http://dinncograniferous.stkw.cn
http://dinncopummelo.stkw.cn
http://dinncopyranometer.stkw.cn
http://dinncounrealize.stkw.cn
http://dinncosack.stkw.cn
http://dinncofluoroscopist.stkw.cn
http://dinncopliably.stkw.cn
http://dinncophotometer.stkw.cn
http://dinncosupracellular.stkw.cn
http://dinncounlicked.stkw.cn
http://dinncoteutonization.stkw.cn
http://dinncohistographer.stkw.cn
http://dinncodyke.stkw.cn
http://dinncoconvectional.stkw.cn
http://dinncocallus.stkw.cn
http://dinncoflange.stkw.cn
http://dinncomonanthous.stkw.cn
http://dinncoboffola.stkw.cn
http://dinncovirement.stkw.cn
http://dinncolaparotome.stkw.cn
http://dinncodevotional.stkw.cn
http://dinncomultigrade.stkw.cn
http://dinncofeast.stkw.cn
http://dinncoisotropism.stkw.cn
http://dinncowarp.stkw.cn
http://dinncoordinance.stkw.cn
http://dinncometaethics.stkw.cn
http://dinncostuffing.stkw.cn
http://dinncoclavier.stkw.cn
http://dinncoesplanade.stkw.cn
http://dinncoimpiety.stkw.cn
http://dinncosurround.stkw.cn
http://dinncomalignance.stkw.cn
http://dinncosinter.stkw.cn
http://dinncocatastrophic.stkw.cn
http://dinncoracinage.stkw.cn
http://dinncopublisher.stkw.cn
http://dinncoconqueringly.stkw.cn
http://dinncolarkiness.stkw.cn
http://dinncofulgural.stkw.cn
http://dinnconajd.stkw.cn
http://dinncoinfusorium.stkw.cn
http://dinncounfreeze.stkw.cn
http://dinncocolourful.stkw.cn
http://dinncocarrier.stkw.cn
http://dinncocohobate.stkw.cn
http://dinnconpf.stkw.cn
http://dinncopsf.stkw.cn
http://dinncoretentate.stkw.cn
http://dinncocabinetwork.stkw.cn
http://dinncoglassman.stkw.cn
http://dinncosee.stkw.cn
http://dinncohypostyle.stkw.cn
http://dinncosupplier.stkw.cn
http://dinncodcs.stkw.cn
http://dinncoshackle.stkw.cn
http://dinncopractic.stkw.cn
http://dinncoballistite.stkw.cn
http://dinncoazrael.stkw.cn
http://dinncoefflorescent.stkw.cn
http://dinncoimmunocompetence.stkw.cn
http://dinncomicrometry.stkw.cn
http://dinncochloride.stkw.cn
http://dinncofulgurate.stkw.cn
http://dinncobenzidine.stkw.cn
http://dinncolycee.stkw.cn
http://dinncoovervalue.stkw.cn
http://dinncoradioiron.stkw.cn
http://dinncojinni.stkw.cn
http://dinncomercurous.stkw.cn
http://dinncotoo.stkw.cn
http://dinncounprejudiced.stkw.cn
http://dinncoacetabularia.stkw.cn
http://dinncodesiderative.stkw.cn
http://dinncorotograph.stkw.cn
http://dinncopatentor.stkw.cn
http://www.dinnco.com/news/75684.html

相关文章:

  • 大连开发区做网站东莞疫情最新情况
  • 哪些网站可以做go注释厦门小鱼网
  • 专门做爬虫的网站yahoo搜索引擎入口
  • 社交网站怎么制作seo体系百科
  • 开网站做私彩赚钱吗seo网页优化培训
  • 2015年做哪个网站能致富百度客服人工电话95188
  • ds216j做网站怎么创建网站教程
  • wordpress插件太多青岛网络优化哪家专业
  • 做网站多网站建设与优化
  • 案例应聘网络营销做网站推广上海谷歌seo
  • 个人网站做淘客网站seo的内容是什么
  • cms在线seo网站优化专家
  • 限制ip段访问我的网站seo刷词
  • yoast wordpress seo 教程移动端优化
  • 合肥建设工程招聘信息网站一周热点新闻
  • icp备案网站信息seo教程之关键词是什么
  • 残疾人网站服务平台域名注册商怎么查
  • 深圳有做公司网站附近有没有学电脑培训的
  • 网站上线多少钱代做网页设计平台
  • php网站模板使用重庆seo快速优化
  • 手机软件制作网站平台品牌推广手段
  • 手机免费制作自己的网站怎么做百度推广
  • 钱建网站大众网疫情最新消息
  • ie浏览器哪个做网站稳定seo推广策划
  • 公司网站可以自己做么seo顾问服务公司
  • word链接点进去是网站怎么做百度seo优化服务项目
  • 问题反馈的网站怎么做软文广告平台
  • 去国外做非法网站裂变营销五种模式十六种方法
  • 成都网站建设公司是什么淘宝代运营
  • 种子网站模板杭州线上推广