一、定义
定义:将对象组合成树形结构以表示“部分-整体”
组合模式使客户端对单个对象和组合对象保持一致的处理
类型:结构型
二、适用场景
希望客户端可以忽略组合对象与单个对象的差异时
处理一个树形结构时
三、优点
清楚地定义分层次的复杂对象,表示对象的全部或者部分层次
让客户端忽略了层次的差异,方便对整个层次结构进行控制。
简化客户端的代码
符合开闭原则
四、缺点
限制类型时会较为复杂
使设计变得更加抽象
五、Coding(场景课程目录,课程。课程目录里可以有多个课程,或者课程目录有多个目录)
1. 创建CatalogComponent 抽象类
/** * 目录组件 */ 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 getNPrice(CatalogComponent catalogComponent){ throw new UnsupportedOperationException("不支持获取价格操作"); } public void print(){ throw new UnsupportedOperationException("不支持打印操作"); } }
2. 创建Course课程类,继承课程目录。课程类中有name和price属性,以及重写getName方法,getPrice方法,和print方法
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 getNPrice(CatalogComponent catalogComponent) { return this.price; } @Override public void print() { System.out.println("课程名称:" + name + " 价格: " + price); } }
3. 创建CourseCatalog 类。里面有多个课程目录。level代码目录等级。
/** * 课程目录 */ 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 String getName(CatalogComponent catalogComponent) { return this.name; } @Override public void add(CatalogComponent catalogComponent) { items.add(catalogComponent); } @Override public void remove(CatalogComponent catalogComponent) { items.remove(catalogComponent); } @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(); } } }
4. 测试
public class Test { public static void main(String[] args) { CatalogComponent javaScriptCourse = new Course("JavaScript基础",400); CatalogComponent typeScriptCourse = new Course("TypeScript基础",300); CatalogComponent javaCourse = new Course("Java基础",200); CatalogComponent javaCourse2 = new Course("Java设计模式",200); CatalogComponent javaCourse3 = new Course("Android课程",300); CatalogComponent javaCourseCatalog = new CourseCatalog("Java课程目录", 2); javaCourseCatalog.add(javaCourse); javaCourseCatalog.add(javaCourse2); javaCourseCatalog.add(javaCourse3); CatalogComponent mainCourseCatalog = new CourseCatalog("课程主目录", 1); mainCourseCatalog.add(javaScriptCourse); mainCourseCatalog.add(typeScriptCourse); mainCourseCatalog.add(javaCourseCatalog); mainCourseCatalog.print(); } }
输出为:
5 UML图
六、在源码中的应用
1.jdk java.awt中的Container类
add方法
public Component add(Component var1) { this.addImpl(var1, (Object)null, -1); return var1; }
2. HashMap
HasMap实现了Map接口,并且putAll测参数为Map
public void putAll(Map<? extends K, ? extends V> var1)
3. Java.util.ArrayList
ArrayList实现List接口,List接口继承自Collection,addAll中参数为Collection
public boolean addAll(Collection<? extends E> var1)
4. Mybatis中SqlNode 接口
public interface SqlNode { boolean apply(DynamicContext var1); }
多个SqlNode对象
public class MixedSqlNode implements SqlNode { private List<SqlNode> contents; public MixedSqlNode(List<SqlNode> contents) { this.contents = contents; } public boolean apply(DynamicContext context) { Iterator i$ = this.contents.iterator(); while(i$.hasNext()) { SqlNode sqlNode = (SqlNode)i$.next(); sqlNode.apply(context); } return true; } }
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!