有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

开关箱的java模式

我有一系列的开关箱,但似乎有点太复杂了。简化它的最佳方法是什么?我在考虑使用策略设计模式

我最初的想法是将sendReport变成一个方法,该方法从每个不同的类调用sendReport。然而,我不知道如何实施这一点。有没有人能给我一些指导,也许能给我一些建议,让我能做些什么来简化这种转换

多谢各位

public static boolean sendReport(AuthToken token, Student client, List<ContactMethod> bestOptions, String data) {
    for (ContactMethod method : bestOptions) {
        switch (method) {
            case TEXT:
                String textMessage = client.getPhoneNumber();
                if (null != textMessage) {
                    TEXT.sendReport(token, client.getFName(), client.getLName(), data, textMessage);
                    return true;
                }
                break;
            case POST:
                String address = client.getAddress();
                String suburb = client.getSuburb();
                String state = client.getState();
                String postcode = client.getPostCode();
                if (null != address && null != suburb &&
                    null != state && null != postcode) {
                    Mail.sendReport(token, client.getFName(), client.getLName(), data, address, suburb, state, postcode);
                    return true;
                }
                break;
            case ELECTRONICMAIL:
                String email = client.getEmailAddress();
                if (null != email) {
                    Email.sendReport(token, client.getFName(), client.getLName(), data, email);
                    return true;
                }
                break;
            case VOICECALL:
                String number = client.getPhoneNumber();
                if (null != number) {
                    PhoneCall.sendReport(token, client.getFName(), client.getLName(), data, number);
                    return true;
                }
                break;
            case FACE_TO_FACE:
                String face2face = client.getFace2Face();
                String personName = client.getPersonName();
                if (null != face2face && null != personName) {
                    Face_To_Face.sendReport(token, client.getFName(), client.getLName(), data, face2face,personName);
                    return true;
                }
                break;
            case MAGIC:
                String magicID = client.getMagic();
                if (null != magicID) {
                    magic.sendReport(token, client.getFName(), client.getLName(), data, magicID);
                    return true;
                }
                break;
            default:
                return false;
        }
    }
    return false;
}

共 (4) 个答案

  1. # 1 楼答案

    我只需将开关“块”转换为方法并调用它们;e、 g

    public static boolean sendReport(AuthToken token, Student client, 
                                     List<ContactMethod> bestOptions,
                                     String data) {
        for (ContactMethod method : bestOptions) {
            boolean res;
            switch (method) {
                case TEXT:
                    res = processText(token, client, data);
                    break;
                case POST:
                    res = processPost(token, client, data);
                    break;
                ...
                default:
                    res = false;
            }
            if (res) {
                return true;
            }
        }
        return false;
    }
    
    private boolean processText(AuthToken token, Student client) {
        String textMessage = client.getPhoneNumber();
        if (null != textMessage) {
            TEXT.sendReport(token, client.getFName(), client.getLName(), 
                            data, textMessage);
            return true;
        } else {
            return false;
        }
    }
    

    当然,您可以用设计模式来修饰它,但简单的过程抽象也可以

  2. # 2 楼答案

    是的,战略/政策模式的实施将完成这项工作。基本上,三个已经存在的答案中有两个显示了该模式的可能实现(Michael's answerAli Gelenler's answer),尽管Michael不认为他的实现会遵循一种模式

    如果可能的联系方法集是固定的,您甚至可以将sendReport()作为方法添加到枚举中,每个枚举实例都有不同的实现。这为策略提供了一个专用的注册表(并且不需要定义几个不同的类)

    更干净的路径是(正如前面提到的答案所建议的那样)定义一个接口ContactMethod,并为您需要的每个联系方法实现该接口。它的优点是,您可以轻松添加其他联系方式(特别是如果您使用java.util.ServiceLoaderAPI)

    缺点是,如果contact方法是外部化实体的一个属性,那么您需要某种策略注册表,以及从策略名称到其实现的映射——正如所说,当您扩展(滥用?)时,您可以免费获得一些东西枚举

  3. # 3 楼答案

    你甚至不需要设计模式,你只需要基本的多态性

    ContactMethod从枚举更改为接口。每个case语句都成为接口的一个实现

    public class TextContactMethod implements ContactMethod { ... }    
    

    sendReport变成

    for (ContactMethod method : bestOptions) {
        method.fooBar(token, client);
    }
    
  4. # 4 楼答案

    定义具有sendReport方法的公共接口ContactMethod,并为实现ContactMethod的每个交换机案例创建不同的实现类。比如,

    public static boolean sendReport(AuthToken token, Student client, List<ContactMethod> bestOptions, String data) {
       for (ContactMethod method : bestOptions) {
          if (method.sendReport(token, client, data))
             return true;
       }
    }
    
    public class TextContactMethod implements ContactMethod {
        public boolean sendReport(AuthToken token, Student client, String data) {
                String textMessage = client.getPhoneNumber();
                if (null != textMessage) {
                    TEXT.sendReport(token, client.getFName(), client.getLName(), data, textMessage);
                    return true;
                }
           return false;
        }
    }