X

曜彤.手记

随记,关于互联网技术、产品与创业

吉 ICP 备10004938号

“行为变化类”设计模式(C++)


在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合。

命令模式(Command)

在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合 —— 比如需要对行为进行“记录、撤销”、“事务”等处理时,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

模式定义:将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

struct Command {
  virtual void execute() = 0;
};
class ConcreteCommandA : public Command {  // 将行为变成对象,并且含有自己的私有参数;
  std::string title;
 public:
  ConcreteCommandA(std::string title) : title(title) {}
  void execute() override {
    std::cout << "[ConcreteCommand A]" << std::endl;
  };
};
struct ConcreteCommandB : public Command {
  void execute() override {
    std::cout << "[ConcreteCommand B]" << std::endl;
  };
};
int main(int argc, char** argv) {
  auto commandA = std::make_shared<ConcreteCommandA>("Title");
  auto commandB = std::make_shared<ConcreteCommandB>();
  std::vector<std::shared_ptr<Command>> vec;  // 行为可以被存储,甚至回放;
  vec.push_back(commandA);
  vec.push_back(commandB);
  for (const auto &command : vec) {
    command->execute();
  }
  return 0;
}

总结:

访问器模式(Visitor)

在软件的构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

模式定义:表示一个作用于某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。

struct ElementA;
struct ElementB;
struct Visitor {
  virtual void visitElementA(ElementA& element) = 0;
  virtual void visitElementB(ElementB& element) = 0;
  virtual ~Visitor() {}
};
struct Element {
  virtual void accept(Visitor& visitor) = 0;  // first dispatch;
  virtual ~Element() {}
};
struct ElementA : public Element {
  void accept(Visitor& visitor) override {
    visitor.visitElementA(*this);
  };
};
struct ElementB : public Element {
  void accept(Visitor& visitor) override {
    visitor.visitElementB(*this);  // second dispatch;
  };
};
/* ---- 上述类型必须是稳定的,下述操作是可变动的 ---- */
struct VisitorA : public Visitor {
  void visitElementA(ElementA& element) override {
    std::cout << "[VisitorA -> visitElementA]" << std::endl;
  };
  void visitElementB(ElementB& element) override {
    std::cout << "[VisitorA -> visitElementB]" << std::endl;
  };
};
struct VisitorB : public Visitor {
  void visitElementA(ElementA& element) override {
    std::cout << "[VisitorB -> visitElementA]" << std::endl;
  };
  void visitElementB(ElementB& element) override {
    std::cout << "[VisitorB -> visitElementB]" << std::endl;
  };
};
int main(int argc, char** argv) {
  VisitorB visitorB;
  ElementB elementB;
  elementB.accept(visitorB);
  return 0;
} 

总结:



这是文章底线,下面是评论
  暂无评论,欢迎勾搭 :)