1. 程式人生 > >面向介面程式設計,介面是什麼,有什麼作用?

面向介面程式設計,介面是什麼,有什麼作用?

  我從接觸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中的統計)、標識實現類是否需要記錄呼叫日誌等等。

當然簡單的專案還是可以省去介面的,沒有必要搞的太複雜,少敲程式碼可以實現相同的功能對於程式設計師來說就是幸福。但這種幸福往往是短暫的(重構和拓展就是噩夢)。