如何在Java中实现模式匹配并避免instanceof?

目前,我不知道如何避免代码中的代码味道。 我尝试了几种模式(策略,访客),但它们没有提供干净且可维护的解决方案。这是我的策略模式代码示例:

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);
        }
    }
}

还有一个对象示例。

public abstract class action {
 abstract void bar();
} 

public class actionOne extends action {
  void bar() {}
}

public class actionTwo extends action {
  void bar() {}
}

我想使这段代码更简洁

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。

xu0612204126 回答:如何在Java中实现模式匹配并避免instanceof?

有两种方法可以解决我的问题。

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

,

可能是这样的:

   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);  }
,

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

类似这样的东西。

public class StrategyFactory {

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

然后,像这样。

Action action = item.getAction();
action.setStrategy(StrategyFactory.getStrategy(action));

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

本文链接:https://www.f2er.com/2793154.html

大家都在问