Android源码看设计模式(九)--------关于组合模式的View和ViewGroup的相关分析

组合模式

定义:

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性

使用场景

  • 表示对象的部分-整体层次的结构时
  • 从一个整体中能够独立出部分模块或者功能的场景

组合模式的写法

组合模式分为两种:安全型组合模式、透明型组合模式

安全型组合模式UML图如下:
这里写图片描述
透明型组合模式UML图如下:
这里写图片描述

  • Component:抽象节点,为组合中的对象声明接口,适当的时候实现所有类的公有接口方法的默认行为。
  • Composite:定义所有枝干节点的行为,存储子节点,实现相关操作。
  • Leaf:叶子节点,没有子节点,实现相关对象的行为。

安全型组合模式实例:
抽象根节点

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<Component> 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<Component> 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("叶子节点没有子节点");
    }
}

View与ViewGroup看组合模式

UML图如下:
这里写图片描述
我们可以看到这里使用的是安全型组合模式

我们跟进一下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

猜你喜欢

转载自blog.csdn.net/qq_33768280/article/details/81123888
今日推荐