我們都知道在java中有(OCP:Open/Closed Principle)原則,對擴展開放,對修改關(guān)閉.但是在實際中如果使用傳統(tǒng)的開發(fā)方式很難做到這一點,比如如下場景:web service dao層中增加用戶業(yè)務邏輯上有變化,如何才能做到不改變原代碼的情況下,對新增功能進行擴展呢?
這里就需要用到java的面向接口編程.接下來將通過這一案例對面向接口編程做演示.
首先:原有環(huán)境如下圖
service層(模擬功能):
package com.xfz.service;
public class UserService1 {
public void addUser(){
System.out.println("增加用戶");
}
}
web層(模擬功能測試)
package com.xfz.web;
import com.xfz.service.UserService1;
public class UserTest {
public static void main(String[] args) {
UserService1 user = new UserService1();
user.addUser();
}
}
現(xiàn)在業(yè)務層用戶功能更新,由于不能在原代碼上進行修改,所以這里在業(yè)務層新建類UserService2來進行模擬:service層UserService2代碼(模擬功能更新):
package com.xfz.service;
public class UserService2 {
public void addUser(){
System.out.println("增加用戶新功能");
}
}
現(xiàn)在業(yè)務層用戶功能更新,由于不能在原代碼上進行修改,所以這里在業(yè)務層新建類UserService2來進行模擬:
到這里問題就來了:現(xiàn)在要實現(xiàn)UserService2的新功能,如果使用傳統(tǒng)方式在web層UserTest下進行創(chuàng)建UserService2類對象調(diào)用方法,那么今后每次增加新功能都將重復進行創(chuàng)建新對象調(diào)用新方法(功能),而這種對原代碼進行修改的方式不符合java 開閉原則,對擴展開放對修改關(guān)閉.所以這里我們將使用面向接口的方式來對web層service層dao層的代碼進行耦合性分離,實現(xiàn)新增功能無需修改原代碼同樣也能實現(xiàn)新增功能.
思想:面向接口編程,解開三層耦合性
步驟:
1.創(chuàng)建UserInterface接口

UserInterface接口代碼:
package com.xfz.service;
public interface UserInterface {
public void addUser();
}
2.UserService1和UserService2實現(xiàn)UserInterface 接口

UserService1代碼:
package com.xfz.service.impl;
import com.xfz.service.UserInterface;
public class UserService1 implements UserInterface{
public void addUser(){
System.out.println("增加用戶");
}
}
UserService2代碼:
package com.xfz.service.impl;
import com.xfz.service.UserInterface;
public class UserService2 implements UserInterface{
public void addUser(){
System.out.println("增加用戶新功能");
}
}
3.在項目根目錄src下創(chuàng)建bean.properties配置文件

bean.properties配置文件內(nèi)容:
#bean工廠的配置,鍵是接口名=值是該接口的實現(xiàn)類
UserInterface=com.xfz.service.impl.UserService2
4.創(chuàng)建工具類(傳入接口生產(chǎn)實現(xiàn)類)

工具類BeanFactory代碼:
package com.xfz.utils;
import java.util.ResourceBundle;
public class BeanFactory {
/**
* 接收接口,返回他的實現(xiàn)類對象
* 接收的是接口的class對象
* 任意類的class對象都是Class對象
*/
public static <T> T getInstance(Class<T> clazz ) {
//讀取配置文件,獲取接口實現(xiàn)類的類名,反射創(chuàng)建對象
//獲取出傳遞的接口名字嗎
String simpleName = clazz.getSimpleName();
ResourceBundle resourceBundle = ResourceBundle.getBundle("bean");
//傳遞接口名作為鍵,獲取值,是實現(xiàn)類的全名
String className = resourceBundle.getString(simpleName);
T t = null;
//反射創(chuàng)建對象
try {
Class cla = Class.forName(className);
//創(chuàng)建該類的對象,返回Object
t = (T) cla.newInstance();
}catch (Exception ex){ex.printStackTrace();}
return t;
}
}
5.web層代碼使用接口接收接口實現(xiàn)類對象(功能塊下所有功能)

web層UserTest代碼
import com.xfz.service.UserInterface;
import com.xfz.service.impl.UserService1;
import com.xfz.utils.BeanFactory;
public class UserTest {
public static void main(String[] args) {
// UserService1 user = new UserService1();
// user.addUser();
UserInterface user = BeanFactory.getInstance(UserInterface.class);
user.addUser();
}
}
右鍵運行后,成功執(zhí)行UserService2新增功能.并且今后擴展相關(guān)功能,原代碼無需在改變,只需在將新功能類在配置文件進行配置即可.

Spring框架基本也是同上原理,不過現(xiàn)在注解開發(fā)也是占主流,但是理解面向接口編程對于今后的知識拓展還是很有幫助的.
以上就是本次面向接口編程案例的演示.有問題歡迎在評論區(qū)進行討論.O(∩_∩)O