# 第八章 邊界 ###### tags: `Tag(Clean Code)` [TOC] ## 大綱 注重邊界的目的在於將自己==不可控的部分==,比如第三方類庫,變成相對可控的部分。至少劃清邊界後,如果是因為第三方類庫版本更新造成的問題,我們可以快速定位並決定是否替換。 軟體設計在於==適應這些改變==,而不是大規模投入或重新撰寫程式,當使用無法控制的程式碼時,特別花工夫去維護,確保不花太多功夫,因應未來的修改。 邊界的程式碼必須清楚分割,定義預期的測試,最好依靠在可以控制的程式上,而不是無法控制程式碼上。 ### 使用第三方軟體程式碼 開源的第三方類庫,有些時候甚至會產生一些我們意料之外的問題,比如兼容性問題,或是類庫更版導致一些方法不再可用等問題。 針對對第三方的類庫進行封裝,新建一個類對需要使用到的第三方類庫進行包裹,如果要使用第三方類庫,就調用這個包裹類,這麼做的好處在於,如果第三方類庫出現問題,我們能夠更快速地定位問題,不至於讓這些陌生的對象充斥在系統的各個角落。 ### 使用尚未存在的程式 尚未被設計出來的API。 ### 探索及學習邊界 ==學習測試(Learning Test)== 學習第三方軟體是件困難的事,整合更是困難,書中採取另一種方法 ,撰寫測試程式碼。 學習測試裡,檢驗API瞭解程度,測試想要重API獲得的結果。 * 寫簡單測試,並不花太多功夫,可以增進對API的了解, * 定義自己的介面,掌握主控權 ## 舉例: ### 學習LOG4J學習log4j 假設我們要使用apache log4j軟件包,而不是我們自己的定制記錄器。我們下載它並打開介紹性文檔頁面。無需過多閱讀,我們就可以編寫第一個測試用例,期望它會向控制台寫入“ hello”。 ``` @Test public void testLogCreate() { Logger logger = Logger.getLogger("MyLogger"); logger.info("hello"); } ``` ==運行時,記錄器會產生一個錯誤==,告訴我們我們需要一個叫做==Appender==的東西。閱讀更多內容後,我們發現有一個ConsoleAppender。因此,我們創建一個==ConsoleAppender==並查看是否已解鎖登錄控制台的秘密。 ``` @Test public void testLogAddAppender() { Logger logger = Logger.getLogger("MyLogger"); ConsoleAppender appender = new ConsoleAppender(); logger.addAppender(appender); logger.info("hello"); } ``` 這次我們發現Appender沒有輸出流。奇怪-它有一個似乎是合乎邏輯的。經過Google的一點幫助之後,我們嘗試以下方法: ``` @Test public void testLogAddAppender() { Logger logger = Logger.getLogger("MyLogger"); logger.removeAllAppenders(); logger.addAppender(new ConsoleAppender( new PatternLayout("%p %t %m%n"), ConsoleAppender.SYSTEM_OUT)); logger.info("hello"); } ``` 閱讀和測試,最終我們得到了清單8-1。我們已經發現了很多有關log4j的工作方式,並且已經將這些知識編碼為一組簡單的單元測試。 --- 初始化一個簡單的控制台日誌器,也能把這些知識封裝到自己的日誌分類中,好將應用程序的其他部分與log4j的邊界接口隔離開來 ``` public class LogTest { private Logger logger; @Before public void initialize() { logger = Logger.getLogger("logger"); logger.removeAllAppenders(); Logger.getRootLogger().removeAllAppenders(); } @Test public void basicLogger() { BasicConfigurator.configure(); logger.info("basicLogger"); } @Test public void addAppenderWithStream() { logger.addAppender(new ConsoleAppender( new PatternLayout("%p %t %m%n"), ConsoleAppender.SYSTEM_OUT)); logger.info("addAppenderWithStream"); } @Test public void addAppenderWithoutStream() { logger.addAppender(new ConsoleAppender( new PatternLayout("%p %t %m%n"))); logger.info("addAppenderWithoutStream"); } } ```
×
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