设计困境。什么是最好的设计?

时间:2015-08-11 07:05:15

标签: java design-patterns

我有一个设计困境,其中:

  1. 我的网页上有一个UI操作,允许用户从类型列表中选择一种类型。

  2. 每种类型都由POJO定义。我需要在父类中包装此POJO(对于用户已选择的类型)并使用它来执行操作。

  3. 每种类型都可能导致不同的行为。

  4. 如何设计父类以支持用户选择的任何类型?我希望在我的应用程序中稍后使用选定的POJO时避免instanceof检查。

3 个答案:

答案 0 :(得分:3)

哪种解决方案最好取决于您在UI中定义选项的方式。

定义可能选择的最简单方法是使用枚举。如果你走这条路线,我建议使用EnumMap将类型映射到动作,或者(假设动作是可变的或需要根据请求创建动作工厂。

例如:

EnumMap<Type, Class<Action>> typeToActionMap = new EnumMap<>();
typeToActionMap.put(Type.Large, LargeAction.class);
typeToActionMap.put(Type.Medium, MediumAction.class);
typeToActionMap.put(Type.Small, SmallAction.class);

上面我使用动作类作为一种工厂。如果动作可以是单例,则可以使地图的值成为动作。正如@dhke建议的那样,你可以使用Guava的ClassToInstanceMap来映射:

ClassToInstanceMap<Action> actionTypeToAction = MutableClassToInstanceMap.create();
typeToActionMap.putInstance(LargeAction.class, new LargeAction(...));
typeToActionMap.putInstance(MediumAction.class, new MediumAction(...));

如果您已经为每个选择设置了唯一类型,那么您只需要找到一种方法来进行映射。一种简单的方法是让您的类型都实现一个通用的接口:

public interface ActionProvider {

  Class<? extends Action> getActionClass();

答案 1 :(得分:1)

实施APP_ABI := all

ActionRegistry

然后,当您在用户界面中选择class ActionRegistry { private static Map<ActionType, AbstractAction> REGISTRY = ... public static void registerAction(AbstractAction a) { REGISTRY.put(a.getType(), a); } public static AbstractAction getAction(ActionType type) { REGISTRY.get(type); } } 时,您可以执行以下操作:

type

您可以试用ActionRegistry.getAction(type).run(); ,因此在实例化其子类时,它会自动在注册表中注册。

答案 2 :(得分:0)

为了避免instanceof,您可以覆盖一个方法,然后执行您需要的UI操作。

public void doAction(Type1 type) { //... }
public void doAction(Type2 type) { //... }

这种方法可以采取多种形式

interface Action {
    void perform();
}

public class ActionFactory {
    public static Action getAction(Type1 type) { //... }
    public static Action getAction(Type2 type) { //... }
}