首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在java中实现模式匹配,避免instanceof?

如何在java中实现模式匹配,避免instanceof?
EN

Stack Overflow用户
提问于 2020-01-10 13:38:40
回答 3查看 399关注 0票数 3

目前,我不知道如何在我的代码片段中避免代码气味。我尝试了几种模式(Strategy,Visitor),但它们都没有提供一个干净和可维护的解决方案。以下是我的策略模式代码的示例:

代码语言:javascript
复制
public interface Strategy {
  <T> T foo(FirstParam firstParam, SecondParam secondParam);
}

public class StrategyOne implements Strategy {
  FirstReturnType foo(FirstParam firstParam, SecondParam secondParam);
}

public class StrategyTwo implements Strategy {
  SecondReturnType foo(FirstParam firstParam, SecondParam secondParam);
}

@Setter
public class Context {
    private Strategy strategy;
    public void execute(FirstParam firstParam, SecondParam secondParam) {
        if (strategy != null) {
            strategy.fo(firstParam, secondParam);
        }
    }
}

这里有一个对象的例子。

代码语言:javascript
复制
public abstract class Action {
 abstract void bar();
} 

public class ActionOne extends Action {
  void bar() {}
}

public class ActionTwo extends Action {
  void bar() {}
}

我想让这段代码变得更干净

代码语言:javascript
复制
public class ActionExecutor {
   private Context context;
   private FirstParam firstParam;
   private SecondParam secondParam;
   public ActionExecutor(FirstParam firstParam, SecondParam secondParam) {
    this.context = new Context();
    this.firstParam = firstParam;
    this.secondParam = secondParam;
   }

  public void doSmth(Item item) {
    Action action = item.getAction();
    if(action instanceof ActionOne) {
     context.setStrategy(new StrategyOne());
    }
    if(action instanceof ActionTwo) {
     context.setStrategy(new StrategyTwo());
    }
    context.execute(firstParam, secondParam);
  }
}

其思想是针对特定的对象类型执行特定的操作。但我不知道如何避免在这种情况下使用instanceof。

EN

回答 3

Stack Overflow用户

发布于 2020-01-10 13:47:08

我头上有两条路。

代码语言:javascript
复制
public abstract class Action {
 public Strategy strategy;
 abstract void bar();
} 

public class ActionOne extends Action {
  void bar() {}
   // set strategy here,  possibly
}

public class ActionTwo extends Action {
  void bar() {}
}

public void doSmth(Item item) {
    Action action = item.getAction();
    action.strategy.execute(firstParam, secondParam);
  }

第二种方法是,在所有操作中使用枚举,并通过在抽象类构造函数中将其声明为参数来强制使用枚举。然后使用switch in而不是instanceof

票数 2
EN

Stack Overflow用户

发布于 2020-01-10 13:51:13

可能是这样的:

代码语言:javascript
复制
   public void doSmth(Item item) {

    Action action = item.getAction();

    Map<String,Strategy> strategies = new HashMap<>();
    strategies.put(ActionOne.getClass().getSimpleName(),new StrategyOne());
    strategies.put(ActionTwo.getClass().getSimpleName(),new StrategyTwo());
    ..
    strategies.put(ActionHundred.getClass().getSimpleName(),new StrategyHundred());

    if(strategies.containsKey(action.getClass().getSimpleName())) {
     context.setStrategy(strategies.get(action.getClass().getSimpleName()));
    }
    context.execute(firstParam, secondParam);  }
票数 2
EN

Stack Overflow用户

发布于 2020-01-10 16:58:46

这看起来像是Factory Method模式的教科书用例。您可以使用与现在相同的代码(或另一个答案中的Map示例),但将其放在工厂中-然后它是特定于特定用途的,并与使用它的代码解耦。

就像这样。

代码语言:javascript
复制
public class StrategyFactory {

    public static Stategy getStrategy(Action action) {
        if(action instanceof ActionOne) {
            return new StrategyOne();
        } else if(action instanceof ActionTwo) {
            return new StrategyTwo();
        }
    }
}

然后,就像这样。

代码语言:javascript
复制
Action action = item.getAction();
action.setStrategy(StrategyFactory.getStrategy(action));

这里还有另一个示例:https://dzone.com/articles/design-patterns-the-strategy-and-factory-patterns

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59676031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档