首页 > 解决方案 > 我如何编写一个名称中不涉及方法逻辑但适应各种算法(在 Java 中)的方法?

问题描述

我正在编写一个 Java 应用程序,该应用程序必须与接受其自己的语言的设备进行通信,该语言通过安全外壳通道由命令序列(一系列字节)组成。

为简单起见,此设备上有命名的读/写字段

  1. fieldAlpha
  2. fieldBeta ...
  3. fieldn

我可以在此设备上获取设置。

命令序列由 StringBuilder 对象创建,该对象由

命令序列看起来像<ESC>ABC*somerandomvalueDEF<LF>.

在写了大约 20 篇之后,我认为必须有一种更易于维护的方式来处理这个问题。

public String getFieldAlpha() {
    StringBuilder sb = new StringBuilder();
    sb.append((char) 0x1B).append("ABC").append("DEF").append((char) 0x0D);
    byte[] command = sb.toString().getBytes();
    String response = (sendMessage(command));
    return response;
}

public String setFieldAlpha(String alpha) {
    StringBuilder sb = new StringBuilder();
    sb.append((char) 0x1B).append("ABC*").append(alpha).append("DEF").append((char) 0x0D);
    byte[] command = sb.toString().getBytes();
    String response = (sendMessage(command));
    return response;
}

public String getFieldBeta() {
    StringBuilder sb = new StringBuilder();
    sb.append((char) 0x1B).append("OPQ").append("RST").append((char) 0x0D);
    byte[] command = sb.toString().getBytes();
    String response = (sendMessage(command));
    return response;
}

public String setFieldBeta(String beta) {
    StringBuilder sb = new StringBuilder();
    sb.append((char) 0x1B).append("OPQ*").append(beta).append("RST").append((char) 0x0D);
    byte[] command = sb.toString().getBytes();
    String response = (sendMessage(command));
    return response;
}

// ... and so forth

我怀疑更好的 API 设计是两种基于参数选择函数的方法。我挂断了命令序列根据字段而变化的事实。

  1. getField()
  2. setField(Method FieldName, String value)

或者有没有更好的方法我没有考虑?我看起来可能使用 Enum Objects 来设置字段命令序列的前缀和后缀。

标签: design-patternsmethodsinterface

解决方案


实现这一点的一种方法是使用将字段映射到消息格式的HashMap 。如果您有不同的格式来获取字段和设置字段,您将需要两个HashMaps

您的应用程序必须为每个字段调用方法,因此您可以添加两个方法:setField(string fieldName, string fieldValue)getField(string fieldName)

您可以添加一个包含字段的静态类。

public class Fields {

  public final string Alpha = "Alpha";
  public final string Alpha = "Beta";
  // ......
}

添加工厂将消息创建的职责分离到一个特殊的对象:

  public class MessageFactory {

    private HashMap<string, string> mFieldNameMessageFormatMap;

    public MessageFactory() {

       mFieldNameMessageFormatMap = HashMap<string, string>();

       // Initialize your formats here. These are just for example and are not 
          correct

       mFieldNameMessageFormatMap.put(Fields.Alpha, "<ESC>ABC*%sDEF<LF>");
       mFieldNameMessageFormatMap.put(Fields.Beta, "<ESC>OPQ*%sRST<LF>");
    }

    public string createGetFielMessage(string fieldName) {
       return String.format(mFieldNameMessageFormatMap.get(fieldName), "");
    }

    public void createSetFieldMessage(string fieldName, string value) {
       return String.format(mFieldNameMessageFormatMap.get(fieldName), value);
    }
  }

然后你的代码变成:

 public void getValue(string fieldName) {
   return sendMessage(mMessageFactory.createGetFieldValue(fieldName));
 }

 public void setValue(string fieldName, string value) {
   return sendMessage(mMessageFactory.createSetFieldValue(fieldName), value);
 }

 // usage:

 string fieldValue = getValue(Fields.Alpha);

 setValue(Fields.Alpha);

添加新字段很容易。您只需将字段添加到Fields类并将格式添加到工厂

这样您就不必为每个字段编写方法,并且您的代码中不会有“魔术字符串”


推荐阅读