PHP草根论之设计模式-訪问者模式
關(guān)于模式本身的概念,請(qǐng)參考網(wǎng)上其他文章
此處僅僅討論在PHP實(shí)際開發(fā)過程中的應(yīng)用
此模式適用范圍極為受限,適用情景:
1.適用于項(xiàng)目維護(hù)過程,不適用于項(xiàng)目開發(fā)過程
2.新增需求,要求為一個(gè)/多個(gè)類添加一個(gè)/多個(gè),同樣/相似的方法
3.原有代碼不能改動(dòng)或擴(kuò)展
4.原有類已經(jīng)預(yù)留了一個(gè)為本模式準(zhǔn)備的接口.
以上,3,4非常難同一時(shí)候在產(chǎn)品維護(hù)過程中同一時(shí)候出現(xiàn).
?
需求:
1.一組對(duì)象,同屬一個(gè)父類或分屬不同父類,使用某一數(shù)據(jù)結(jié)構(gòu)組成一個(gè)數(shù)據(jù)集,此處的數(shù)據(jù)結(jié)構(gòu)能夠是概念意義上的隊(duì)列,棧,集合,樹,圖或?qū)嶋H意義上的一維或多維數(shù)組,僅僅要能夠遍歷就可以
2.項(xiàng)目須要對(duì)以上對(duì)象添加一個(gè)操作,以便在遍歷整組對(duì)象時(shí),同名調(diào)用.
?
實(shí)現(xiàn)過程:
1.原有代碼中,以上對(duì)象所屬的類,事先預(yù)留了一個(gè)擴(kuò)展接口,能夠叫做accept(奇怪的名字)
Class ElementA{
public function accept(VisitorBase $v){
$v->visitA($this);
}
}
class ElementB{
public function accept(VisitorBase $v){
$v->visitB($this);
}
?
}
依據(jù)以上,我們當(dāng)然要事先定義一個(gè)VisitorBase的抽象接口
interface VisitorBase {
function visitA(ElementA $eleA);
function visitB(ElementB $eleB);
}
2.新的代碼中,我們?yōu)樾略龅牟僮鲃?chuàng)建一個(gè)類,叫做VisitorX(訪問者,又是一個(gè)奇怪的名稱),假設(shè)有還有一個(gè)操作,能夠定義為VisitorY,均實(shí)現(xiàn)了VisitorBase接口
class VisitorX implements VisitorBase{
public function visitA(ElementA $eleA){
//此處能夠訪問元素A的方法以處理詳細(xì)事務(wù)
$eleA->someFunc();
}
public function visitB(ElementB $eleB){
……
}
}
3.新的代碼中,我們能夠遍歷,以數(shù)組為例(這個(gè)最經(jīng)常使用了)
??? $x=new VisitorX;
??? foreach($elementArray as $element){
??????? $element->accept($x);
??? }
??? 以上將遍歷全部元素(不管是否同一父類),對(duì)每個(gè)元素運(yùn)行VisitorX類中的對(duì)應(yīng)操作.
草根觀點(diǎn):
??? 1.憑什么原有代碼不讓改動(dòng)?僅僅是加個(gè)方法而已.
??? 2.我不改原有代碼,還不讓我繼承一下,擴(kuò)展一個(gè)方法?
??? 3.原有代碼定義擴(kuò)展接口了么?
曾經(jīng)的程序猿有這么前瞻?
??? 4.僅僅要有其他方式實(shí)現(xiàn)同等功能,盡量不要使用此設(shè)計(jì)模式, 這將導(dǎo)致對(duì)同一對(duì)象的操作代碼分散在程序的不同位置,不利于進(jìn)一步的維護(hù)與改動(dòng).
??? 5.可考慮的替代實(shí)現(xiàn)方法:
?????? A.改動(dòng)原有類,添加一個(gè)同名方法
?????? B.擴(kuò)展(繼承)原有類,添加一個(gè)同名方法
?????? C.假設(shè)一定要將不同類的同一操作的代碼集中在一起,那么考慮Trait吧
總結(jié)
以上是生活随笔為你收集整理的PHP草根论之设计模式-訪问者模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决visual studio已安装的问
- 下一篇: python性能分析