将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
组合模式分为两种:安全型组合模式、透明型组合模式
安全型组合模式实例:
抽象根节点
public abstract class Component {
protected String name; //节点名
public Component(String name){
this.name = name;
}
/**
* 具体方法由子类实现
*/
public abstract void doSomething();
}
枝干节点
public class Composite extends Component{
/**
* 存储根节点的容器
*/
private List components = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void doSomething() {
System.out.println(name);
if (null != components) {
for (Component c : components) {
c.doSomething();
}
}
}
/**
* 添加子节点
* @param child
*/
public void addChild(Component child) {
components.add(child);
}
/**
* 移除子节点
* @param child
*/
public void removeChild(Component child) {
components.remove(child);
}
/**
* 获得子节点
* @param index
* @return
*/
public Component getChildren(int index) {
return components.get(index);
}
}
具体子节点
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void doSomething() {
System.out.println(name);
}
}
安全型组合模式实例:
抽象根节点
public abstract class Component {
protected String name; //节点名
public Component(String name) {
this.name = name;
}
/**
* 具体方法由子类实现
*/
public abstract void doSomething();
/**
* 添加子节点
*
* @param child
*/
public abstract void addChild(Component child);
/**
* 移除子节点
*
* @param child
*/
public abstract void removeChild(Component child);
/**
* 获得子节点
*
* @param index
* @return
*/
public abstract Component getChildren(int index);
}
枝干节点
//同安全型组合模式一样
public class Composite extends Component{
private List components = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void doSomething() {
System.out.println(name);
if (null != components) {
for (Component c : components) {
c.doSomething();
}
}
}
public void addChild(Component child) {
components.add(child);
}
public void removeChild(Component child) {
components.remove(child);
}
public Component getChildren(int index) {
return components.get(index);
}
}
具体子节点
//在具体方法实现中判断
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void doSomething() {
System.out.println(name);
}
@Override
public void addChild(Component child) {
throw new UnsupportedOperationException("叶子节点没有子节点");
}
@Override
public void removeChild(Component child) {
throw new UnsupportedOperationException("叶子节点没有子节点");
}
@Override
public Component getChildren(int index) {
throw new UnsupportedOperationException("叶子节点没有子节点");
}
}
我们跟进一下ViewGroup的源码:
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
....
//添加子视图
public void addView(View child) {
addView(child, -1);
}
//移除子视图
public void removeView(View view) {
if (removeViewInternal(view)) {
requestLayout();
invalidate(true);
}
}
//获取子视图
public View getChildAt(int index) {
if (index < 0 || index >= mChildrenCount) {
return null;
}
return mChildren[index];
}
....
}
但是我们知道View中是没有这些方法的,那么关键就在ViewGroup实现的接口上,我们接着来看ViewManager
public interface ViewManager{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
再来看ViewParent
public interface ViewParent {
/**
请求重新布局
*/
public void requestLayout();
/**
是否已经请求重新布局,应当注意的是requestLayout调用之后,并不是立刻就执行,Android会将请求布局的操作以消息
的形式发送至主线程的Handler并由其分发处理
*/
public boolean isLayoutRequested();
/**
获取当前View的ViewParent对象
*/
public ViewParent getParent();
/**
请求子视图的焦点
*/
public void requestChildFocus(View child, View focused);
....
}
组合模式可以清楚的定义分层次的复杂对象,表示对象的全部或者部分层次,方便对整个层次结构进行控制,但是也有其弊端,在新增构件时不好对枝干中的构件类型进行限制,因为在很多的情况下,它们都是来自于相同的抽象层,必须进行类型检查,比较麻烦
《Android源码设计模式解析与实战》
https://blog.csdn.net/qq_25806863/article/details/69568341