当实现仅在单个方法中有所不同时,建议使用哪种设计模式?

时间:2016-03-30 15:05:54

标签: java oop inheritance design-patterns abstract-class

我有一个界面,有6种方法用于管理数据集。实现之间唯一不同的方法是getSerializedVersion()和能够解析序列化字符串的构造函数。

public interface DataSets {
  public void addEntry(...);
  public void  removeEntry(...);
  public void manipulateEntry(...);
  public SomeType getEntry(...);
  public List<SomeType> getAllEntries();
  // This differs:
  public String getSerializedVersion()
}

我无法更改界面。

我的第一个想法是生成一个抽象类并实现前五个方法。对于具体实现(例如DataSetsXMLDataSetsYAML,...),我只需要实现getSerializedVersion()以及能够读取String并初始化对象的构造函数。

为了使其更易于测试,不同的设计可能会更好(https://stackoverflow.com/a/7569581),但哪一个?

答案可能是主观的,但我认为不同方法有一些一般规则或至少(客观)优点和缺点,......

2 个答案:

答案 0 :(得分:9)

根据您的解释,差异是与类的行为无关的东西,而是它是如何序列化和反序列化的。我的意思是DataSetsXMLDataSetsYAML具有相同的功能,但它们会被序列化为不同的格式。

这意味着保持getSerializedVersion()DataSets类相结合没有任何好处。你应该完全解耦它们。

您可以使用序列化界面:

interface DataSetsSerializer
{
  public DataSets unserialize(String string);
  public String serialize(DataSets sets);
}

然后在这个类中处理不同的实现,例如:

class YAMLDataSetsSerializer implements DataSetsSerializer
{
  public DataSets unserialize(String string) {
    DataSets sets = new DataSets();
    ...
  }

  public String serialize(DataSets sets) {
    ...
  }
}

通过详细阐述JB Nizet评论,如果你必须在DataSetsSerializer实例中保留一个DataSets(恕我直言,因为它们在任何情况下都应该解耦,因为它是一种特定的序列化方式不应该绑定到要序列化的数据)然后方法如下:

class DataSets {
  final private DataSetsSerializer serializer;

  public DataSets(DataSetsSerializer serializer, String data) {
    this.serializer = serializer;
    serializer.unserialize(this, data);
  }

  @Override
  public String getSerializedVersion() {
    return serializer.serialize(this);
  }
}

这需要对建议的界面稍作改动,这不是一个聪明的设计,但它尊重您的要求。

答案 1 :(得分:1)

我认为使用抽象类是合理的。您可以测试抽象类的具体实现(它也间接测试抽象类)。