我從接觸java編程開始,書上、網上看到的都是面向接口編程,雖然一臉懵逼,但也沒有多想,這個和每個人的學習習慣有關系吧,我一直都是奉行着what how why的學習原則,管他是什么妥妥的就是干(copy),別人這么干我也這么干。公司里最常見的Spring 業務邏輯層應該是這樣的:
接口
public interface UserService { User findByUsername(String username); }
實現類
@Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDao dao;
@Override
public User findByUsername(String username) { return dao.findByUsername(username); } }
在很長一段時間里不明白為什么要這樣做,也沒有去深入研究,以至於再后來開發的時候直接去掉了實現類UserServiceImpl變成了這樣
@Service @Transactional public class UserService { @Autowired private UserDao dao; public User findByUsername(String username) { return dao.findByUsername(username); } }
妥妥的沒毛病,程序少了接口,代碼都可以少敲點(幸福來的好突然)。在很長一段時間里整個公司都是這么干的,直到遇到了大一點項目(分布式部署,系統之間產生了交互),然后對接口有了新的認識,以下是自己對接口的一些理解。
很多其他行業在計算機面世之前就已經發展很久了,所以接口並不是計算機程序特有的,可以說接口無處不在。生活中很熟悉的插座

賣插座的廠商不一定會生產插頭,但是普通家電的三線插頭都是按照這樣的規范設計的,為了保證可以完美插入像這樣


當然香港買的腎7什么的,他的充電器插頭就不好插了,好尷尬WTF


像這樣的插頭就需要轉接頭了(設計模式中的適配器模式),廠商是按照不一樣的標准生成的,大陸有大陸的標准,香港有香港的標准。
接口是規范
插座是為了規范插頭生產廠商,USB接口是為了規范USB生產廠商,程序的接口是為了規范什么呢?為了規范廣大不同經驗不用閱歷的程序猿,為了實現類與類之間的松耦合。調用者只要按照接口規范傳入入參接口就會返回期望的出參(結果),具體是怎么實現的(內部結構,業務邏輯)調用者無需關心(像不像領導,只要結果不要過程,領導規定並調用接口,我們去實現)。
public interface SortService<T extends Comparable> { void sort(T[] array); }

SortService的sort方法是給數組正序排序,在數組長度小的時候可能用簡單排序,冒泡排序就行了,大一點用歸並排序,在大一點用快速排序。對於調用者來說只關注排序的結果,不關注過程。
面向接口編程在協同開發的時候也是非常有作用的,假設兩個開發人員A和B一起開發一個商品購買的功能,商品購買的流程假設分為:庫存查詢和付款,
A負責開發查詢庫存,B負責開發付款;
A在查詢庫存返回還有庫存后需要調用付款流程;
B提供付款接口給A,A調用接口獲得付款結果;
B是怎么實現付款的,A不需要知道,哪天現有的付款邏輯不合適了,B重新開發了,也不會影響整個流程。
付款接口就是規范了B必須要按照接口的方法名,方法入參和出參類型來寫實現類。
接口是協議
http協議大家應該很熟悉(客戶端請求指定的地址可以當做是服務端提供的一個接口),請求報文格式如下:

服務器按照http約定的報文格式解析報文,客戶端按照http約定的報文格式提交報文獲得響應數據,至於服務器是怎么產生這些數據的客戶端不需要知道,客戶端只需請求服務器提供的鏈接地址就能獲取想要的數據,服務器和客戶端之間就實現了請求-響應的通信。
最近開發的一個項目由多個子項目構成,項目與項目之間要相互調用對方的接口,項目里使用Hessian框架實現遠程接口調用,項目只需將接口和Dto打成jar包給客戶端,客戶端就能像使用本地的Bean一樣,實現調用了(Hessian真是簡單粗暴)。將接口暴露給客戶端,實現隱藏起來。
客戶端和服務端按照約定的協議進行數據交互,服務端按照約定的協議提供接口。
接口是標識
標識實現類可以做什么,不可以做什么,例如:java.io.Serializable接口,此接口沒有任何方法和字段,只是標識實現類是否可以序列化和反序列化。像這樣的空接口在實際開發中還有很多其他作用,比如標識實現類是否需要統計調用方法的執行時間(druid中的統計)、標識實現類是否需要記錄調用日志等等。
當然簡單的項目還是可以省去接口的,沒有必要搞的太復雜,少敲代碼可以實現相同的功能對於程序員來說就是幸福。但這種幸福往往是短暫的(重構和拓展就是噩夢)。
