本节通过两个简单设计模式实例来了解诶面向接口编程
一、简单工厂模式
场景:程序中有个Computer类需要组合一个输出设备,但是并不能确定该输出设备是什么,可能是打印机,也可能是显示器等
首先模拟一台此场景下的计算机
public class Computer { //计算机的输出设备接口 private Output output; //计算机构造器。需要指定输出设备 public Computer(Output output){ this.output = output; } //模拟输入,输入后将输入值传输给输出设备 public void input(String msg){ output.getData(msg); } //计算机发出打印指令,调用输出设备的打印方法 public void print(){ output.out(); } }
如果把输出设备定义为一个输出借口,就可以应用于各种输出设备。
所以需要定义输出接口规范
import java.util.HashMap; import java.util.Map; //输出设备接口 public interface Output { //系统会自动为接口里定义的成员变量添加public static final 修饰符 //输出设备输出队列最大容量 public static final int MAX_SIZE = 50; //接口里定义的普通方法为public的抽象方法 //输出设备的输出方法 void out(); //输出设备的读取数据的方法 void getData(String msg); //java8支持的默认方法,可以写body //输出设备的默认输出方法 default void print(String... msgs){ for(String msg : msgs){ System.out.println(msg); } } default void test(){ System.out.println("默认的test方法"); } //定义类方法需要用static修饰 static void staticTest(){ return "接口里的类方法"; } }
2 命令模式
这时就为这台计算机耦合了输出设备接口,但是还没有输出接口的实现类,所以调用输出方法。
引入输出设备工厂来为电脑类指定输出设备,这里就是用引入第三方工厂类的方式来消除电脑类和具体输出设备类的耦合关系,与之前的“剧本-导演-演员”相同
public class OutputFactory { public Output getOutput(){ return new Printer(); } public static void main(String[] args) { OutputFactory outputFactory = new OutputFactory(); Computer c = new Computer(outputFactory.getOutput()); c.input(""); c.print(); } }
利用getOutput方法可以获取任意的输出设备,只要它们符合Output接口规范,这边是面向接口编程的简单工厂模式。(Printer 类的具体实现类没有贴出)
二、命令模式
场景:某个方法需要完成某一个行为,但是该行为的具体实现无法直接指定,需要等到执行该方法时才可以确定,我们需要在调用该方法时指定具体的处理行为,所以设计一个命令接口,调用方法时参数列表中传入一个实现命令接口的对象,由该对象来制定具体的执行方法。代码如下
public class ProcessArray{ //处理数组类封装一个处理的方法 //该方法为需要完成某一行为的方法,在这里行为是处理数组,但是具体处理方式没有确定 public void process(int[] target, Command cmd){ cmd.process(target); } }
//命令接口规范 public interface Command{ //声明命令接口通过命令调用的方法 void process(int[] target); }
public class CommandTest{ public static void main(String[] args){ ProcessArray pa = new ProcessArray(); int[] target = {1,2,3,4}; pa.process(target , new PrintCommand()); pa.process(target , new AddCommand()); } }
在这里具体的实现Command接口的类并未贴出。通过这种方法实现process()方法和具体的处理行为的分离