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

时间:2018-04-14 10:02:51

标签: c++ design-patterns

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

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;
    } 
};

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

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

所以我最终可以得到更多的Formater对象(Formater1,Formater2 ......)。

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

2 个答案:

答案 0 :(得分:1)

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

{
  "markets": ["us", "uk", "ca"]
}

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

答案 1 :(得分:0)

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

这里是Bridge Pattern的{​​{1}}定义:将抽象与其实现分离,以便两者可以独立变化。