从对象映射到动态字符串

时间:2010-11-15 22:54:38

标签: java

现在我有大约60个Message类型,这些类型被传递给实现getStuff(Message)的类的ContainerOfThings方法。 ContainerOfThings有多种变体,例如BoxOfStuffBagOfTricks,它们都实现了基于成员变量生成字符串的getStuff(Message)方法。结果还可能包含预先标记或后标记的数据,例如标签或连接数据。请参阅下面的代码。

public class BoxOfStuff implements ContainerOfThings
{
    private String var1;
    private String var2;
    private String varN; 

    public String getStuff(Message message)
    {
        if (message.equals(Message.GET_STUFF1))
            return var1;
        else if (message.equals(Message.GET_STUFF2))
            return "Var2 is: " + var2;
        else if (message.equals(Message.GET_STUFFN))
            return varN + "\n";
        // Etc. for each Message.GET_*
    }
    // getters and setters for each var*
}

public class Message
{
    private String id = null;

    private Message(String id)
    {       this.id = id;   }

    public final String toString()
    {       return this.id; }

    public static final Message GET_STUFF1 = new Message("V1");
    public static final Message GET_STUFF2 = new Message("V2");
    public static final Message GET_STUFFN = new Message("VN");

}

我正在努力寻找符合以下目标的设计。 (1)从getStuf()返回的字符串需要反映实现类的成员字段的当前状态。 (2)此外,我宁愿远离一系列令人难以置信的if / else if块。一个问题是易于改变为持久的数据驱动的可配置对象方法,Map可以很好地实现。 (3)设计应允许简单的维护和/或编辑。

一个可以工作但有点混乱的设计是创建一个Map,其中包含在构造函数中初始化的所有键/值,并重置每个setter方法中的任何键/值对。通过这种方式,对getStuff(Message)的响应在更改后更新为新内容(即:在setVar*()方法中)。还有其他想法吗?

3 个答案:

答案 0 :(得分:1)

我不是100%确定我理解您的问题,但听起来您希望memoize getStuff()来电的结果。

一种简单的方法是使用Google makeComputingMap()库中MapMaker类的Guava方法。

例如,你可以这样做:

Map<Message, String> map = new MapMaker()
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .makeComputingMap(
       new Function<Message, String>() {
         public String apply(Message message) {
             // Your getStuff() implementation here
         }
       });

这有意义吗?

答案 1 :(得分:1)

我想你需要两张地图。一个是Map<Message, String>,其中值将是格式字符串(即将传递到String.format()的内容)。第二张地图将是Map<Message, Field>,一旦你看一下反射库,它应该是相当自我解释的。这些将需要在初始化时设置,但在此之后getStuff()方法应该相当干净,并且您的setter根本不会受到影响。

BTW,Java通常不会在接口前加上I

答案 2 :(得分:0)

这个怎么样:

public abstract class BaseOfBox implements IContainerOfThings {
    protected final Map<Message, String> stuffs = 
            new HashMap<Message, String>();

    public final String getStuff(Message message) {
        return stuffs.get(message);
    }
}

public class BoxOfStuff extends BaseOfBox {
    private String var1;
    private String var2;

    public BoxOfStuff() {
        super();
    }

    public setVar1(String var1) {
        this.var1 = var1;
        stuffs.put(Message.GET_STUFF1, var1);
    }

    public setVar2(String var2) {
        this.var2 = var2;
        stuffs.put(Message.GET_STUFF2, "Var2 is: " + var2);
    }
    ...
}

坦率地说,我认为这是一个非常难看的解决方案,但IMO的要求也是如此。我怀疑只有在审查(实际)要求时才能找到更优雅的解决方案