亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3046 | 回復(fù): 0
打印 上一主題 下一主題

[zt]用Adapter模式取代部分實現(xiàn)的接口 Kerievsky(原作) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2002-09-30 09:34 |只看該作者 |倒序瀏覽
Refactoring to Patterns : 用Adapter模式取代部分實現(xiàn)的接口    Kerievsky(原作)  
  
關(guān)鍵字     refactoring pattern
  


用Adapter模式取代部分實現(xiàn)的接口
撰文/Joshua Kerievsky             編譯/透明



你的類實現(xiàn)一個接口,但是只為接口中的一部分方法提供代碼。

將實現(xiàn)的方法移交給該接口的適配器,并讓一個工廠方法可以訪問該適配器。



動機(jī)
       具體類中的空方法總是讓我很煩心。我經(jīng)?匆娨恍┛辗椒,因為具體類經(jīng)常需要通過實現(xiàn)某個接口來滿足某種要求,但又不是真的需要實現(xiàn)接口中所有的方法。不需要的方法得到了聲明,但是保留為空:添加它們僅僅是為了滿足編譯器的規(guī)則。這可能不會讓你煩心,但的確讓我很煩心。我發(fā)現(xiàn),類的接口(即public方法集合)中如果出現(xiàn)空方法,不但會使類的接口變得臃腫,還會對類的行為做出錯誤的宣傳(我是一個類,我可以做X()、Y()和Z()——但我其實只提供X()的代碼),而且強(qiáng)迫我做一些不想做的工作(比如聲明一些空方法)。



       Adapter模式提供了一種重構(gòu)這種代碼的好方法。Adapter類將給接口中所有的方法一個空的實現(xiàn),而你則可以從Adapter類派生出需要的子類,同時只需要提供需要的代碼。在Java中,我甚至不需要正式聲明一個Adapter子類:我只需要在Adapter類中創(chuàng)建一個匿名子類,然后直接將它的引用提供給Factory Method就行了。



通信
重復(fù)
簡化

不管是有人忘了刪掉空方法還是因為接口強(qiáng)迫你保留空方法,類中的空方法都不會有太多的通信。最好是只在真正實現(xiàn)的時候才進(jìn)行通信,而Adapter可以幫助你實現(xiàn)這一點。
如果你有不止一個類部分實現(xiàn)了同一個接口,那么你可能擁有相當(dāng)多的空方法了。只要讓這些類都與一個處理空方法聲明的Adapter類協(xié)同工作,你就可以去掉這些重復(fù)。
提供少量代碼總比提供大量代碼要容易。這個重構(gòu)方法給你一種方法以減少類中聲明的方法數(shù)量。另外,當(dāng)你用這種方法來適配多個接口時,它可以提供一條非常好的途徑,讓你可以實現(xiàn)每個接口中的一部分方法。




技巧
1.       如果還沒有要使用的接口(我把它叫做A)的適配器,就用“適配接口”的方法來創(chuàng)建一個。然后創(chuàng)建一個Factory Method模式,讓它返回你的適配器的一個實例(我把它叫做AdapterInstance)。

2.       把你的類中那些完全因為實現(xiàn)A接口才存在的空方法刪掉。

3.       把你實現(xiàn)了的那些由A指定的方法轉(zhuǎn)移到AdapterInstance中。

4.       刪除你的類中“implements A”的聲明。

5.       把AdapterInstance提供給需要的客戶。



示例
       我將用具體的代碼來說明上面的步驟。在這里我們有一個名叫CardComponent的類,它派生自JDK中的Component類,并實現(xiàn)JDK中的MouseMotionListener接口。但是,它只實現(xiàn)MouseMotionListener接口的兩個方法中的一個。讓我們看看Adapter模式怎樣改善這段代碼。



第一步,為我們的AdapterInstance創(chuàng)建一個Factory Method。如果我們還沒有AdapterInstance,我們就需要用“適配接口”的重構(gòu)方法來創(chuàng)建一個。在這里,JDK已經(jīng)為MouseMotionListener接口提供了一個適配器,名叫MouseMotionAdapter。所以我們在CardComponet類中創(chuàng)建下列新方法,其中使用了Java便利的內(nèi)部類能力:

private MouseMotionAdapter createMouseMotionAdapter() {

return new MouseMotionAdapter() {

}&#59;

}



       接著,我們刪掉CardComponent中聲明的空方法,因為它在MouseMotionListener已經(jīng)被實現(xiàn)了。在這里,MouseMotionListener實現(xiàn)了mouseDragged方法,但沒有實現(xiàn)mouseMoved方法。

public void mouseMoved(MouseEvent e) {}



       現(xiàn)在我們已經(jīng)將mouseDragged方法從CardComponent方法中移到了MouseMotionAdapter的實例中。

private MouseMotionAdapter createMouseMotionAdapter() {

return new MouseMotionAdapter() {

public void mouseDragged(MouseEvent e) {

e.consume()&#59;

dragPos.x = e.getX()&#59;

dragPos.y = e.getY()&#59;

setLocation(getLocation().x+e.getX()-currPos.x,

getLocation().y+e.getY()-currPos.y)&#59;

repaint()&#59;

}

}&#59;

}



       現(xiàn)在我們可以從CardComponent中刪掉MouseMotionListener的實現(xiàn)了。

       public class CardComponent extends Container implements MouseMotionListener {



       最后,我們必須將新的適配器實例提供給需要的客戶。在這里,我們必須觀察構(gòu)造子,它的代碼是這樣:

public CardComponent() {

//……

addMouseMotionListener(this)&#59;

}

需要將它改為調(diào)用新的私有工廠方法:

public CardComponent() {

//…

addMouseMotionListener(createMouseMotionAdapter())&#59;

}



       現(xiàn)在我們進(jìn)行測試。很不幸,因為這段代碼與鼠標(biāo)相關(guān),我無法進(jìn)行自動化單元測試。因此我進(jìn)行了一些簡單的手工測試,并確認(rèn):我們的重構(gòu)很成功。



附錄:源代碼
l        重構(gòu)前:

public class CardComponent extends Container implements MouseMotionListener ...

public CardComponent(Card card,Explanations explanations) {

//...

addMouseMotionListener(this)&#59;

}

public void mouseDragged(MouseEvent e) {

e.consume()&#59;

dragPos.x = e.getX()&#59;

dragPos.y = e.getY()&#59;

setLocation(getLocation().x+e.getX()-currPos.x, getLocation().y+e.getY()-currPos.y)&#59;

repaint()&#59;

}

public void mouseMoved(MouseEvent e) {

}



l        重構(gòu)后:

public class CardComponent extends Container ...

public CardComponent(Card card,Explanations explanations) {

//...

addMouseMotionListener(createMouseMotionAdapter())&#59;

}

private MouseMotionAdapter createMouseMotionAdapter() {

return new MouseMotionAdapter() {

public void mouseDragged(MouseEvent e) {

e.consume()&#59;

dragPos.x = e.getX()&#59;

dragPos.y = e.getY()&#59;

setLocation(getLocation().x+e.getX()-currPos.x, getLocation().y+e.getY()-currPos.y)&#59;

repaint()&#59;

}

}&#59;

}


您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP