dljd_(001_002)_通过接口降低程序的耦合度
一、需求
假设让我们写一个人驾驶迈腾的功能,那么我们如何去设计?
二、功能实现
2.1一般人会通过聚合的方式实现
聚合:是一种强的关联关系。是整体和个体之间的关系。如胳膊类和人类。个人理解聚合关系是一种have a的拥有关系。
package edu.aeon.demo; /** * [说明]:迈腾类 * @author aeon(qq:1584875179) * */ public class MaiTen { /** * 行驶 */ public void run(){ System.out.println("MaiTen.run()"); System.out.println("迈腾在行驶!"); } /** * 停止 */ public void stop(){ System.out.println("MaiTen.stop()"); System.out.println("迈腾停下来了!"); } }
package edu.aeon.demo; /** * [说明]:人类 * @author aeon(qq:1584875179) * */ public class Person { private MaiTen maiTen; //getter/setter public MaiTen getMaiTen() { return maiTen; } public void setMaiTen(MaiTen maiTen) { this.maiTen = maiTen; } /** * 驾驶 */ public void drive(){ System.out.println("Person.drive()"); maiTen.run(); maiTen.stop(); } }
package edu.aeon.demo; /** * [说明]:测试类 * @author aeon(qq:1584875179) * */ public class Test { public static void main(String[] args) { Person person=new Person(); MaiTen maiTen=new MaiTen(); person.setMaiTen(maiTen); person.drive(); } }
测试结果截图:
二、使用依赖关系
依赖关系是类与类之间的联接。一个类依赖于另一个类的定义。如人驾驶迈腾必须要依赖迈腾。
package edu.aeon.demo; /** * [说明]:迈腾类 * @author aeon(qq:1584875179) * */ public class MaiTen { /** * 行驶 */ public void run(){ System.out.println("MaiTen.run()"); System.out.println("迈腾在行驶!"); } /** * 停止 */ public void stop(){ System.out.println("MaiTen.stop()"); System.out.println("迈腾停下来了!"); } }
package edu.aeon.demo; /** * [说明]:人类 * @author aeon(qq:1584875179) * */ public class Person { /** * 驾驶 */ public void drive(MaiTen maiTen){ System.out.println("Person.drive()"); maiTen.run(); maiTen.stop(); } }
package edu.aeon.demo; /** * [说明]:测试类 * @author aeon(qq:1584875179) * */ public class Test { public static void main(String[] args) { Person person=new Person(); MaiTen maiTen=new MaiTen(); person.drive(maiTen); } }
测试结果截图:
我们可以看出来,聚合关系和依赖关系都可以实现这个需求,但是我们想想这样设计的缺陷是什么?加入后面需求变化了,让人去驾驶一辆宝马,该如何办呢?是不是要频繁的去更改源码,假如需求一直在变化,让人去驾驶奔驰、比亚迪,...这样我们一而再再而三的频繁更改源码,显然这种结果不是我们想要的,怎么去设计一个更易于后期拓展和维护的呢?请看接下来的这种。
三、面向接口实现
package edu.aeon.demo; /** * [说明]:车接口 * @author aeon(qq:1584875179) * */ public interface Car { //行驶 void run(); //停止 void stop(); }
package edu.aeon.demo; /** * [说明]:人类 * @author aeon(qq:1584875179) * */ public class Person { /** * 驾驶 */ public void drive(Car car){ System.out.println("Person.drive()"); car.run(); car.stop(); } }
package edu.aeon.demo; /** * [说明]:迈腾类 * @author aeon(qq:1584875179) * */ public class MaiTen implements Car { /** * 行驶 */ public void run(){ System.out.println("MaiTen.run()"); System.out.println("迈腾在行驶!"); } /** * 停止 */ public void stop(){ System.out.println("MaiTen.stop()"); System.out.println("迈腾停下来了!"); } }
package edu.aeon.demo; /** * [说明]:宝马类 * @author aeon(qq:1584875179) * */ public class BMW implements Car { /** * 宝马:行驶 */ @Override public void run() { System.out.println("BMW.run()"); System.out.println("宝马开始行驶"); } /** * 宝马:停止 */ @Override public void stop() { System.out.println("BMW.stop()"); System.out.println("宝马停下来了!"); } }
package edu.aeon.demo; /** * [说明]:测试类 * @author aeon(qq:1584875179) * */ public class Test { public static void main(String[] args) { Person person=new Person(); Car maiTen=new MaiTen(); Car bmw=new BMW(); person.drive(maiTen); System.out.println("========================="); person.drive(bmw); } }
测试结果截图:
package edu.aeon.demo; /** * [说明]:根据不同职位提供不同的车 * @author aeon(qq:1584875179) * */ public class Office { public Car getCar(String job){ if("CEO".equals(job)){ return new MaiTen(); }else if("部门经理".equals(job)){ return new BMW(); }else{ System.out.println("你所提供职位暂不提供车辆!"); return null; } } }
package edu.aeon.demo; /** * [说明]:测试类 * @author aeon(qq:1584875179) * */ public class Test { public static void main(String[] args) { Person person=new Person(); Car maiTen=new MaiTen(); Car bmw=new BMW(); Office office=new Office(); Car car=office.getCar("CEO"); person.drive(maiTen); System.out.println("========================="); person.drive(bmw); System.out.println("========================="); person.drive(car); } }
测试结果截图:
以后编程中我们主要以面向接口编程:
3.1声明变量
3.2方法参数
3.3返回值类型
可见这种面向接口编程带来的效果显而易见,当以后需求变化时,我们只需添加新的类(实现Car接口),而不需要去频繁的更改源码,这种设计大大降低了代码之间的耦合度,大大的降低了后期的维护成本和难度,非常易于扩展。所以我们以后编程都要有这种思维模式。