日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

《研磨设计模式》chap25 访问者模式Visitor(3)联合组合模式+总结

發(fā)布時(shí)間:2025/3/21 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《研磨设计模式》chap25 访问者模式Visitor(3)联合组合模式+总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 聯(lián)合組合模式

//抽象的組件對(duì)象,相當(dāng)于訪問者模式中的元素對(duì)象 public abstract class Component {//接受訪問者的訪問 public abstract void accept(Visitor visitor);//向組合對(duì)象中加入組件對(duì)象 public void addChild(Component child) {// 缺省的實(shí)現(xiàn),拋出例外,因?yàn)槿~子對(duì)象沒有這個(gè)功能,或者子組件沒有實(shí)現(xiàn)這個(gè)功能throw new UnsupportedOperationException("對(duì)象不支持這個(gè)功能"); }//從組合對(duì)象中移出某個(gè)組件對(duì)象 public void removeChild(Component child) {// 缺省的實(shí)現(xiàn),拋出例外,因?yàn)槿~子對(duì)象沒有這個(gè)功能,或者子組件沒有實(shí)現(xiàn)這個(gè)功能throw new UnsupportedOperationException("對(duì)象不支持這個(gè)功能"); }// 返回某個(gè)索引對(duì)應(yīng)的組件對(duì)象 public Component getChildren(int index) {throw new UnsupportedOperationException("對(duì)象不支持這個(gè)功能");} }public class Leaf extends Component{public void accept(Visitor visitor) {//回調(diào)訪問者對(duì)象的相應(yīng)方法visitor.visitLeaf(this);}private String name = ""; //葉子對(duì)象的名字 public Leaf(String name){this.name = name;}public String getName() {return name;} }//循環(huán)子元素,讓子元素也接受訪問 public class Composite extends Component{public void accept(Visitor visitor) {//回調(diào)訪問者對(duì)象的相應(yīng)方法visitor.visitComposite(this);//循環(huán)子元素,讓子元素也接受訪問for(Component c : childComponents){//調(diào)用子對(duì)象接受訪問,變相實(shí)現(xiàn)遞歸c.accept(visitor);}}//用來存儲(chǔ)組合對(duì)象中包含的子組件對(duì)象 private List<Component> childComponents = new ArrayList<Component>(); private String name = "";//組合對(duì)象的名字 public Composite(String name){this.name = name;} public void addChild(Component child) {childComponents.add(child);}public String getName() {return name;} }public interface Visitor {//訪問組合對(duì)象,相當(dāng)于給組合對(duì)象添加訪問者的功能 public void visitComposite(Composite composite);//訪問葉子對(duì)象,相當(dāng)于給葉子對(duì)象添加訪問者的功能 public void visitLeaf(Leaf leaf); }public class PrintNameVisitor implements Visitor {public void visitComposite(Composite composite) {//訪問到組合對(duì)象的數(shù)據(jù)System.out.println("節(jié)點(diǎn):"+composite.getName());}public void visitLeaf(Leaf leaf) {//訪問到葉子對(duì)象的數(shù)據(jù) System.out.println("葉子:"+leaf.getName());} }public class ObjectStructure {//表示對(duì)象結(jié)構(gòu),可以是一個(gè)組合結(jié)構(gòu) private Component root = null;public void handleRequest(Visitor visitor){//讓組合對(duì)象結(jié)構(gòu)中的根元素,接受訪問//在組合對(duì)象結(jié)構(gòu)中已經(jīng)實(shí)現(xiàn)了元素的遍歷if(root!=null){root.accept(visitor);}}// 傳入組合對(duì)象結(jié)構(gòu) public void setRoot(Component ele){this.root = ele;} }public static void main(String[] args) {//定義所有的組合對(duì)象Component root = new Composite("服裝");Component c1 = new Composite("男裝");Component c2 = new Composite("女裝");//定義所有的葉子對(duì)象Component leaf1 = new Leaf("襯衣");Component leaf2 = new Leaf("夾克");Component leaf3 = new Leaf("裙子");Component leaf4 = new Leaf("套裝");//按照樹的結(jié)構(gòu)來組合組合對(duì)象和葉子對(duì)象root.addChild(c1);root.addChild(c2);c1.addChild(leaf1);c1.addChild(leaf2);c2.addChild(leaf3);c2.addChild(leaf4);//創(chuàng)建ObjectStructureObjectStructure os = new ObjectStructure();os.setRoot(root);//調(diào)用ObjectStructure來處理請(qǐng)求功能Visitor psVisitor = new PrintNameVisitor(); // root.accept(psVisitor); os.handleRequest(psVisitor);//或者去掉ObjectStructure //調(diào)用根元素的方法來接受請(qǐng)求功能Visitor psVisitor = new PrintStructVisitor(); root.accept(psVisitor); }

1.1.有的時(shí)候可以省略O(shè)bjectStructure ,client直接調(diào)用

1.2. 改造版

假設(shè)要輸出下面的結(jié)果:定制“+”、“-”

public class PrintStructVisitor implements Visitor { private String preStr = "";//用來累計(jì)記錄對(duì)象需要向后退的格public void visitComposite(Composite composite) {//先把自己輸出去System.out.println(preStr+"+"+composite.getName());//如果還包含有子組件,那么就輸出這些子組件對(duì)象if(composite.getChildComponents()!=null){//然后添加一個(gè)空格,表示向后縮進(jìn)一個(gè)空格preStr+=" "; //輸出當(dāng)前對(duì)象的子對(duì)象了for(Component c : composite.getChildComponents()){//遞歸輸出每個(gè)子對(duì)象c.accept(this);}//把循環(huán)子對(duì)象所多加入的一個(gè)退格給去掉preStr = preStr.substring(0,preStr.length()-1);}}public void visitLeaf(Leaf leaf) {//訪問到葉子對(duì)象的數(shù)據(jù) System.out.println(preStr+"-"+leaf.getName());} }

2. 總結(jié)

2.1 訪問者模式有以下缺點(diǎn)

對(duì)象結(jié)構(gòu)變化很困難
不適用于對(duì)象結(jié)構(gòu)中的類經(jīng)常變化的情況,因?yàn)閷?duì)象結(jié)構(gòu)發(fā)生了改變,訪問者的接口和訪問者的實(shí)現(xiàn)都要發(fā)生相應(yīng)的改變,代價(jià)太高。
破壞封裝
訪問者模式通常需要對(duì)象結(jié)構(gòu)開放內(nèi)部數(shù)據(jù)給訪問者和ObjectStructrue,這破壞了對(duì)象的封裝性。

2.2 訪問者模式的本質(zhì):預(yù)留通路,回調(diào)實(shí)現(xiàn)。

仔細(xì)思考訪問者模式,它的實(shí)現(xiàn)主要是通過預(yù)先定義好調(diào)用的通路,在被訪問的對(duì)象上定義accept方法,在訪問者的對(duì)象上定義visit方法;然后在調(diào)用真正發(fā)生的時(shí)候,通過兩次分發(fā)技術(shù),利用預(yù)先定義好的通路,回調(diào)到訪問者具體的實(shí)現(xiàn)上。
明白了訪問者模式的本質(zhì),就可以在定義一些通用功能,或者設(shè)計(jì)工具類的時(shí)候讓訪問者模式派上大用場(chǎng)。你可以把已經(jīng)實(shí)現(xiàn)好的一些功能作為已有的對(duì)象結(jié)構(gòu),因?yàn)樵诮窈罂赡軙?huì)根據(jù)實(shí)際需要為它們?cè)黾有碌墓δ?#xff0c;甚至希望開放接口來讓其他開發(fā)人員擴(kuò)展這些功能,所以你可以用訪問者模式來設(shè)計(jì),在這個(gè)對(duì)象結(jié)構(gòu)上預(yù)留好通用的調(diào)用通路,在以后添加功能,或者是其他開發(fā)人員來擴(kuò)展的時(shí)候,只需要提供新的訪問者實(shí)現(xiàn),就能夠很好地加入到系統(tǒng)中來了。

2.3 建議在以下情況中選用訪問者模式。

如果想對(duì)一個(gè)對(duì)象結(jié)構(gòu)實(shí)施一些依賴于對(duì)象結(jié)構(gòu)中具體類的操作,可以使用訪問者模式。
如果想對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的各個(gè)元素進(jìn)行很多不同的而且不相關(guān)的操作,為了避免這些操作使類變得雜亂,可以使用訪問者模式。把這些操作分散到不同的訪問者對(duì)象中去,每個(gè)訪問者對(duì)象實(shí)現(xiàn)同一類功能。
如果對(duì)象結(jié)構(gòu)很少變動(dòng),但是需要經(jīng)常給對(duì)象結(jié)構(gòu)中的元素對(duì)象定義新的操作,可以使用訪問者模式。

總結(jié)

以上是生活随笔為你收集整理的《研磨设计模式》chap25 访问者模式Visitor(3)联合组合模式+总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。