# “基於接口而非實現編程”的原則 這條原則能非常有效地提高代碼質量,之所以這麼說,那是因為,應用這條原則,可以將接口和實現相分離,封裝不穩定的實現,暴露穩定的接口。上游系統面向接口而非實現編程,不依賴不穩定的實現細節,這樣當實現發生變化的時候,上游系統的代碼基本上不需要做改動,以此來降低耦合性,提高擴展性。 ``` public class AliyunImageStore { //...省略属性、构造函数等... public void createBucketIfNotExisting(String bucketName) { // ...创建bucket代码逻辑... // ...失败会抛出异常.. } public String generateAccessToken() { // ...根据accesskey/secrectkey等生成access token } public String uploadToAliyun(Image image, String bucketName, String accessToken) { //...上传图片到阿里云... //...返回图片存储在阿里云上的地址(url)... } public Image downloadFromAliyun(String url, String accessToken) { //...从阿里云下载图片... } } // AliyunImageStore类的使用举例 public class ImageProcessingJob { private static final String BUCKET_NAME = "ai_images_bucket"; //...省略其他无关代码... public void process() { Image image = ...; //处理图片,并封装为Image对象 AliyunImageStore imageStore = new AliyunImageStore(/*省略参数*/); imageStore.createBucketIfNotExisting(BUCKET_NAME); String accessToken = imageStore.generateAccessToken(); imagestore.uploadToAliyun(image, BUCKET_NAME, accessToken); } } ``` 1. 函數的命名不能暴露任何實現細節。比如,前面提到的 uploadToAliyun() 就不符合要求,應該改為去掉 aliyun 這樣的字眼,改為更加抽像的命名方式,比如:upload()。 2. 封裝具體的實現細節。比如,跟阿裡雲相關的特殊上傳(或下載)流程不應該暴露給調用者。我們對上傳(或下載)流程進行封裝,對外提供一個包裹所有上傳(或下載)細節的方法,給調用者使用。 3. 為實現類定義抽像的接口。具體的實現類都依賴統一的接口定義,遵從一致的上傳功能協議。使用者依賴接口,而不是具體的實現類來編程。 ``` public class AliyunImageStore { //...省略属性、构造函数等... public void createBucketIfNotExisting(String bucketName) { // ...创建bucket代码逻辑... // ...失败会抛出异常.. } public String generateAccessToken() { // ...根据accesskey/secrectkey等生成access token } public String uploadToAliyun(Image image, String bucketName, String accessToken) { //...上传图片到阿里云... //...返回图片存储在阿里云上的地址(url)... } public Image downloadFromAliyun(String url, String accessToken) { //...从阿里云下载图片... } } // AliyunImageStore类的使用举例 public class ImageProcessingJob { private static final String BUCKET_NAME = "ai_images_bucket"; //...省略其他无关代码... public void process() { Image image = ...; //处理图片,并封装为Image对象 AliyunImageStore imageStore = new AliyunImageStore(/*省略参数*/); imageStore.createBucketIfNotExisting(BUCKET_NAME); String accessToken = imageStore.generateAccessToken(); imagestore.uploadToAliyun(image, BUCKET_NAME, accessToken); } } ``` --- ### 是否需要為每個類定義接口? 從這個設計初衷上來看,如果在我們的業務場景中,某個功能只有一種實現方式,未來也不可能被其他實現方式替換,那我們就沒有必要為其設計接口,也沒有必要基於接口編程,直接使用實現類就可以了。除此之外,越是不穩定的系統,我們越是要在代碼的擴展性、維護性上下功夫。相反,如果某個系統特別穩定,在開發完之後,基本上不需要做維護,那我們就沒有必要為其擴展性,投入不必要的開發時間。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up