組合模式
1. 分析
-
定義
將對象組合成樹形結構以表示 “部分-整體” 的層次結構組合模式使客戶端對單個對象和組合對象保持一致的方式處理
-
類型
結構型
-
適用場景
希望客戶端可以忽略組合對象對單個對象的差異時
處理一個樹形結構時 -
優點
清楚的定義分層次的複雜對象,表示對象的全部或部分層次讓客戶端忽略層次的差異,方便對整個層次結構進行控制
簡化客戶端代碼
符合開閉原則
-
缺點
限制類型時會較爲複雜使設計變得更加抽象
-
模式比較
組合模式和訪問者模式
可以使用訪問者模式訪問組合模式中的遞歸結構
2. 示例
public abstract class CatalogComponent {
public void add(CatalogComponent catalogComponent) {
throw new UnsupportedOperationException("不支持添加操作");
}
public void remove(CatalogComponent catalogComponent) {
throw new UnsupportedOperationException("不支持刪除操作");
}
public String getName(CatalogComponent catalogComponent) {
throw new UnsupportedOperationException("不支持獲取名稱操作");
}
public double getPrice(CatalogComponent catalogComponent) {
throw new UnsupportedOperationException("不支持獲取價格操作");
}
public void print() {
throw new UnsupportedOperationException("不支持打印操作");
}
}
public class Course extends CatalogComponent {
private String name;
private double price;
public Course(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public double getPrice(CatalogComponent catalogComponent) {
return this.price;
}
@Override
public void print() {
System.out.println("Course Name: "+this.name + "\tPrice: " + this.price);
}
}
public class CourseCatalog extends CatalogComponent {
private List<CatalogComponent> items = new ArrayList<>();
private String name;
private Integer level;
public CourseCatalog(String name, Integer level) {
this.name = name;
this.level = level;
}
@Override
public void add(CatalogComponent catalogComponent) {
items.add(catalogComponent);
}
@Override
public void remove(CatalogComponent catalogComponent) {
items.remove(catalogComponent);
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public void print() {
System.out.println(this.name);
for (CatalogComponent catalogComponent : items) {
if (this.level != null) {
for (int i = 0; i < this.level; i++) {
System.out.print(" ");
}
}
catalogComponent.print();
}
}
}
public class Test {
public static void main(String[] args) {
CatalogComponent linuxCourse = new Course("Linux課程", 15);
CatalogComponent windowsCourse = new Course("windows課程", 13);
CatalogComponent coreCatalog = new CourseCatalog("課程主目錄", 1);
CatalogComponent javaCourseCatalog = new CourseCatalog("Java課程目錄", 2);
CatalogComponent mallCourse1 = new Course("Java電商課程第一期", 23);
CatalogComponent mallCourse2 = new Course("Java電商課程第二期", 20);
CatalogComponent mallCourse3 = new Course("Java電商課程第三期", 22);
CatalogComponent designPattern = new Course("Java設計模式", 28);
coreCatalog.add(linuxCourse);
coreCatalog.add(windowsCourse);
javaCourseCatalog.add(mallCourse1);
javaCourseCatalog.add(mallCourse2);
javaCourseCatalog.add(mallCourse3);
javaCourseCatalog.add(designPattern);
coreCatalog.add(javaCourseCatalog);
coreCatalog.print();
}
}
3. 源碼
java.awt.Container
java.util.HashMap
putAll 方法
java.util.ArrayList
addAll 方法
org.apache.ibatis.scripting.xmltags.SqlNode