本示例的目的是展示如何使用Java 8功能接口实现策略模式。我们将从经典Java中的简单用例代码开始,然后以Java 8方式对其进行重新编码。
我们使用的示例问题是一系列算法(策略),描述了远距离通信的不同方式。
我们的算法系列的合同由以下接口定义:
public interface CommunicateInterface { public String communicate(String destination); }
然后,我们可以实现许多算法,如下所示:
public class CommunicateViaPhone implements CommunicateInterface { @Override public String communicate(String destination) { return "communicating " + destination +" via Phone.."; } } public class CommunicateViaEmail implements CommunicateInterface { @Override public String communicate(String destination) { return "communicating " + destination + " via Email.."; } } public class CommunicateViaVideo implements CommunicateInterface { @Override public String communicate(String destination) { return "communicating " + destination + " via Video.."; } }
这些可以实例化如下:
CommunicateViaPhone communicateViaPhone = new CommunicateViaPhone(); CommunicateViaEmail communicateViaEmail = new CommunicateViaEmail(); CommunicateViaVideo communicateViaVideo = new CommunicateViaVideo();
接下来,我们实现使用该策略的服务:
public class CommunicationService { private CommunicateInterface communcationMeans; public void setCommuncationMeans(CommunicateInterface communcationMeans) { this.communcationMeans= communcationMeans; } public void communicate(String destination) { this.communcationMeans.communicate(destination); } }
最后,我们可以使用以下不同策略:
CommunicationService communicationService = new CommunicationService(); // 通过电话 communicationService.setCommuncationMeans(communicateViaPhone); communicationService.communicate("1234567"); // 通过电子邮件 communicationService.setCommuncationMeans(communicateViaEmail); communicationService.communicate("hi@me.com");
不同算法实现的协定不需要专用接口。相反,我们可以使用现有java.util.function.Function<T, R>接口对其进行描述。
组成不同的算法the family of algorithms可以表示为lambda表达式。这取代了战略类和它们的实例。
Function<String, String> communicateViaEmail = destination -> "communicating " + destination + " via Email.."; Function<String, String> communicateViaPhone = destination -> "communicating " + destination + " via Phone.."; Function<String, String> communicateViaVideo = destination -> "communicating " + destination + " via Video..";
接下来,我们可以对“服务”进行如下编码:
public class CommunicationService { private Function<String, String> communcationMeans; public void setCommuncationMeans(Function<String, String> communcationMeans) { this.communcationMeans= communcationMeans; } public void communicate(String destination) { this.communcationMeans.communicate(destination); } }
最后,我们使用以下策略
CommunicationService communicationService = new CommunicationService(); // 通过电话 communicationService.setCommuncationMeans(communicateViaPhone); communicationService.communicate("1234567"); // 通过电子邮件 communicationService.setCommuncationMeans(communicateViaEmail); communicationService.communicate("hi@me.com");
甚至:
communicationService.setCommuncationMeans( destination -> "communicating " + destination + " via Smoke signals.." ); CommunicationService.communicate("anyone");