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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

没有性能瓶颈的无限极菜单树应该这样设计

發布時間:2023/12/29 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 没有性能瓶颈的无限极菜单树应该这样设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文節選自《設計模式就該這樣學》

1 使用透明組合模式實現課程目錄結構

以一門網絡課程為例,我們設計一個課程的關系結構。比如,我們有Java入門課程、人工智能課程、Java設計模式、源碼分析、軟技能等,而Java設計模式、源碼分析、軟技能又屬于Java架構師系列課程包,每個課程的定價都不一樣。但是,這些課程不論怎么組合,都有一些共性,而且是整體和部分的關系,可以用組合模式來設計。首先創建一個頂層的抽象組件CourseComponent類。

/*** Created by Tom.*/ public abstract class CourseComponent {public void addChild(CourseComponent catalogComponent){throw new UnsupportedOperationException("不支持添加操作");}public void removeChild(CourseComponent catalogComponent){throw new UnsupportedOperationException("不支持刪除操作");}public String getName(CourseComponent catalogComponent){throw new UnsupportedOperationException("不支持獲取名稱操作");}public double getPrice(CourseComponent catalogComponent){throw new UnsupportedOperationException("不支持獲取價格操作");}public void print(){throw new UnsupportedOperationException("不支持打印操作");}}

把所有可能用到的方法都定義到這個頂層的抽象組件中,但是不寫任何邏輯處理的代碼,而是直接拋異常。這里,有些小伙伴會有疑惑,為什么不用抽象方法?因為用了抽象方法,其子類就必須實現,這樣便體現不出各子類的細微差異。所以子類繼承此抽象類后,只需要重寫有差異的方法覆蓋父類的方法即可。然后分別創建課程Course類和課程包CoursePackage類。創建Course類的代碼如下。

/*** Created by Tom.*/ public class Course extends CourseComponent {private String name;private double price;public Course(String name, double price) {this.name = name;this.price = price;}@Overridepublic String getName(CourseComponent catalogComponent) {return this.name;}@Overridepublic double getPrice(CourseComponent catalogComponent) {return this.price;}@Overridepublic void print() {System.out.println(name + " (¥" + price + "元)");}}

創建CoursePackage類的代碼如下。

/*** Created by Tom.*/ public class CoursePackage extends CourseComponent {private List<CourseComponent> items = new ArrayList<CourseComponent>();private String name;private Integer level;public CoursePackage(String name, Integer level) {this.name = name;this.level = level;}@Overridepublic void addChild(CourseComponent catalogComponent) {items.add(catalogComponent);}@Overridepublic String getName(CourseComponent catalogComponent) {return this.name;}@Overridepublic void removeChild(CourseComponent catalogComponent) {items.remove(catalogComponent);}@Overridepublic void print() {System.out.println(this.name);for(CourseComponent catalogComponent : items){//控制顯示格式if(this.level != null){for(int i = 0; i < this.level; i ++){//打印空格控制格式System.out.print(" ");}for(int i = 0; i < this.level; i ++){//每一行開始打印一個+號if(i == 0){ System.out.print("+"); }System.out.print("-");}}//打印標題catalogComponent.print();}}}

最后編寫客戶端測試代碼。

public static void main(String[] args) {System.out.println("============透明組合模式===========");CourseComponent javaBase = new Course("Java入門課程",8280);CourseComponent ai = new Course("人工智能",5000);CourseComponent packageCourse = new CoursePackage("Java架構師課程",2);CourseComponent design = new Course("Java設計模式",1500);CourseComponent source = new Course("源碼分析",2000);CourseComponent softSkill = new Course("軟技能",3000);packageCourse.addChild(design);packageCourse.addChild(source);packageCourse.addChild(softSkill);CourseComponent catalog = new CoursePackage("課程主目錄",1);catalog.addChild(javaBase);catalog.addChild(ai);catalog.addChild(packageCourse);catalog.print();}

運行結果如下圖所示。

透明組合模式把所有公共方法都定義在 Component 中,這樣客戶端就不需要區分操作對象是葉子節點還是樹枝節點;但是,葉子節點會繼承一些它不需要(管理子類操作的方法)的方法,這與設計模式的接口隔離原則相違背。

2 使用安全組合模式實現無限級文件系統

再舉一個程序員更熟悉的例子。對于程序員來說,電腦是每天都要接觸的。電腦的文件系統其實就是一個典型的樹形結構,目錄包含文件夾和文件,文件夾里面又可以包含文件夾和文件。下面用代碼來實現一個目錄系統。文件系統有兩個大的層次:文件夾和文件。其中,文件夾能容納其他層次,為樹枝節點;文件是最小單位,為葉子節點。由于目錄系統層次較少,且樹枝節點(文件夾)結構相對穩定,而文件其實可以有很多類型,所以我們選擇使用安全組合模式來實現目錄系統,可以避免為葉子節點類型(文件)引入冗余方法。首先創建頂層的抽象組件Directory類。

public abstract class Directory {protected String name;public Directory(String name) {this.name = name;}public abstract void show();}

然后分別創建File類和Folder類。創建File類的代碼如下。

public class File extends Directory {public File(String name) {super(name);}@Overridepublic void show() {System.out.println(this.name);}}

創建Folder類的代碼如下。

import java.util.ArrayList; import java.util.List;public class Folder extends Directory {private List<Directory> dirs;private Integer level;public Folder(String name,Integer level) {super(name);this.level = level;this.dirs = new ArrayList<Directory>();}@Overridepublic void show() {System.out.println(this.name);for (Directory dir : this.dirs) {//控制顯示格式if(this.level != null){for(int i = 0; i < this.level; i ++){//打印空格控制格式System.out.print(" ");}for(int i = 0; i < this.level; i ++){//每一行開始打印一個+號if(i == 0){ System.out.print("+"); }System.out.print("-");}}//打印名稱dir.show();}}public boolean add(Directory dir) {return this.dirs.add(dir);}public boolean remove(Directory dir) {return this.dirs.remove(dir);}public Directory get(int index) {return this.dirs.get(index);}public void list(){for (Directory dir : this.dirs) {System.out.println(dir.name);}}}

注意,Folder類不僅覆蓋了頂層的show()方法,還增加了list()方法。最后編寫客戶端測試代碼。

public static void main(String[] args) {System.out.println("============安全組合模式===========");File qq = new File("QQ.exe");File wx = new File("微信.exe");Folder office = new Folder("辦公軟件",2);File word = new File("Word.exe");File ppt = new File("PowerPoint.exe");File excel = new File("Excel.exe");office.add(word);office.add(ppt);office.add(excel);Folder wps = new Folder("金山軟件",3);wps.add(new File("WPS.exe"));office.add(wps);Folder root = new Folder("根目錄",1);root.add(qq);root.add(wx);root.add(office);System.out.println("----------show()方法效果-----------");root.show();System.out.println("----------list()方法效果-----------");root.list();}

運行結果如下圖所示。

安全組合模式的好處是接口定義職責清晰,符合設計模式的單一職責原則和接口隔離原則;缺點是客戶需要區分樹枝節點和葉子節點,這樣才能正確處理各個層次的操作,客戶端無法依賴抽象接口(Component),違背了設計模式的依賴倒置原則。

本文為“Tom彈架構”原創,轉載請注明出處。技術在于分享,我分享我快樂!

如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支持是我堅持創作的動力。關注微信公眾號『 Tom彈架構 』可獲取更多技術干貨!

本文分享自微信公眾號 - Tom彈架構(gh_e3be84a8ccb2)。
如有侵權,請聯系 support@oschina.cn 刪除。
本文參與“ ?OSC源創計劃? ”,歡迎正在閱讀的你也加入,一起分享。

總結

以上是生活随笔為你收集整理的没有性能瓶颈的无限极菜单树应该这样设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。