如何设计对象以不同方式设置文本格式



我有一个项目,可以根据应用程序所处的某些状态和模式打印一些数据。

enum Mode {
   mode1 = 0,
   mode2
};
enum State {
   state1 = 0,
   state2
};

数据可以通过多种方式打印,以下是一些示例:

1. name1 value1 name2 value2 name3 value3
2. value1 value2 value3
3. name1 : value1.  
   name2 : value2   
   name3 : value3  

我试图用 ostream 运算符重载创建一个类:

class Formater {
public:
   Formater(.....) { ... } // pass name, value, mode, state here.
   virtual void print_State1_Mode1(ostream& os) { }
   virtual void print_State1_Mode2(ostream& os) { }
   virtual void print_State2_Mode1(ostream& os) { }
   virtual void print_State2_Mode2(ostream& os) { }
    friend std::ostream& operator << (std::ostream& os, const Formater& f) {
        if (state1 & mode1) {
            print_State1_Mode1(os);
        }
        else if(state1 & mode2) {
            print_State1_Mode2(os);
        }
        else if(state2 & mode1) {
            print_State2_Mode1(os);
        }
        else {
            print_State2_Mode2(os);
        }
        return os;
    } 
};

这将用于某些命令,并且每个命令(取决于状态和模式(可以具有不同的格式来打印文本。

因此,如果我的对象无法满足命令,我会从它继承并创建一个新命令并覆盖其中一个虚拟方法,具体取决于我需要新格式的模式和状态。

所以我最终可以得到更多的格式化器对象(格式化器1,格式化器2....(。

我对这种方法不是 100% 满意。有没有人有更好的设计或我可以改进当前设计的方法?

我不

明白为什么这个简单的设计是不够的。

class Formatter {
  ...
  virtual std::ostream& insert(std::ostream&) const = 0;
  friend std::ostream& operator<<(std::ostream& os, const Formatter& fmt) {
    return fmt.insert(os); 
  }
};
class Formatter_State1_Mode1: public Formatter {
  ...
  std::ostream& insert(std::ostream&) const override;
};
class Formatter_State1_Mode2: public Formatter {
  ...
  std::ostream& insert(std::ostream&) const override;
};
Formatter* makeFormatter(Mode, State, ...);

它摆脱了丑陋的 if-else-ladder 并产生更好的性能。

我建议你在这里使用Bridge模式。为此,您的功能应仔细分解为两部分。所以你的状态应该是抽象的或精炼的抽象。Formatter将是Implementor.然后,您可以将不同的格式化程序作为ConcreteImplementors。您可以使用AbstractFactory说FormatterFactory来获取基于某些配置属性的格式化程序。这个逻辑应该由你自己定义。

这是Gang of Four Bridge Pattern定义:将抽象与其实现分离,以便两者可以独立变化。

最新更新