TellDontAsk的扩展
五年多來,Martin Fowler在他著名的TellDontAsk文章中指出了面向對象編程中的最大問題之一。 在他的著作中,他提醒程序員,他們應該信任自己的對象來為他們執行工作,而不是要求對象提供以后可以使用的數據。
我非常同意這一點,但是,當然,僅憑此原則并不能保證我們的代碼是面向對象的。 我認為僅僅依靠一個對象來完成工作是不夠的–需要做更多的設計工作,以確保該對象以后不會引起程序代碼。
湯姆和杰瑞–藍貓布魯斯,威廉·漢娜和約瑟夫·巴貝拉
讓我們來看一個例子:
/*** All employees of a company.* You can hire more, fire some of them, give them a raise etc.\*/ public final class AllEmployees implements Employees {//constructor//other methods from Employees interface (hire, fire, raise etc)@Overridepublic List<Employee> filter(final Map<String, String> skills) {//return the List of those who have the specified skills.}}上面的類將創建一個尊重福勒先生原則的適當對象:它將照顧員工,甚至會為我們篩選員工,而不會提出任何問題。 但是,這可能會導致周圍的損壞,原因如下:執行過濾后,我們將剩下一個可以區分所有人的List !
那些被篩選的員工永遠都不會加薪嗎? 他們將永遠不會被解雇,還是我們永遠不會雇用具有相同技能的人(相同的過濾器)? 當然,我們仍然會愿意加薪,解雇或雇用類似的人,但是我們現在已經不在上下文中了,我們手中只有一個愚蠢的List :為了使清單上的員工享有相同的權利,并且其余的義務一樣,我們將需要編寫過程代碼(也許很多代碼)。
我認為應該這樣做:我們應該添加一個新的Employees實現,稱為FilteredEmployees ,該實現會將Map放入其構造函數中,并確保它僅處理具有我們所要求技能的員工。 這樣,他們仍然在同一家公司工作,除了現在我們更加了解他們,我們知道他們擁有一些別人沒有的技能以外,沒有任何改變。 我們不必編寫代碼來處理或轉換 List ,我們仍將有一個Employees實例。 現在我們的班級看起來像這樣:
/*** All employees of a company.* You can hire more, fire some of them, give them a raise etc.\*/ public final class AllEmployees implements Employees {//constructor//other methods from Employees interface (hire, fire, raise etc)@Overridepublic Employees filter(final Map<String, String> skills) {return new FilteredEmployees(..., skills);}}我想說的是,這種想法本身就是試圖實現這種情況,而不是告訴一個對象將您引向上述情況。 也就是說,我們實現了這些已過濾的員工,因為原始對象在維護上下文的同時無法為我們執行過濾。 簡單地告訴目標對象去做就會使我們陷入相同的境地(與具有特定技能的人一起工作),但是這些人不再是雇員 ,而只是列表。
我將所有這些視為對TellDontAsk原理的擴展。 我不確定如何確保您朝正確的方向前進。 但是,我認為JDK(或您使用的任何開發套件)的使用是一個很好的指示: 在面向對象的代碼庫中,該套件應盡可能離散 。 使用開發套件的次數越多,您的代碼實際面向對象的次數就越少,或者您的抽象并不是最好的。 另一方面,僅通過使用現有對象(或添加現有接口的新實現)就能添加/修改/刪除功能越多,則應用程序的面向對象越多。
PS 這是同一想法的另一個示例。
翻譯自: https://www.javacodegeeks.com/2018/11/extension-telldontask.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的TellDontAsk的扩展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 老电脑升级配置方案老电脑如何升级配置
- 下一篇: 五金反引号