Android 最常用的设计模式二 安卓源码分析——组合模式(component)

伪代码如下:

public void testComponent(){
    Composite root = new Composite("服装--根节点");
Composite c1 = new Composite("男装-----一级子节点1");
Composite c2 = new Composite("女装-----一级子节点2");

Leaf leaf1 = new Leaf("衬衫------二级子节点1");
Leaf leaf2 = new Leaf("夹克------二级子节点2");
Leaf leaf3 = new Leaf("裙子------二级子节点3");
Leaf leaf4 = new Leaf("套装------二级子节点4");

root.addChild(c1);
root.addChild(c2);

c1.addChild(leaf1);
c1.addChild(leaf2);
c1.addChild(leaf3);
c1.addChild(leaf4);

c2.addChild(leaf1);
c2.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);


//所有的服装的消费记录
root.paycard("");
}
public class Composite implements IComponent {


    /**
     * 用来存储组合对象中包含的子组件对象
*/
private List childComponents = new ArrayList();
/**
     * 组合对象的名字
*/
private String name;
/**
     * 构造方法,传入组合对象的名字
* @param name    组合对象的名字
*/
public Composite(String name){
        this.name = name;
}
    /**
     * 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(IComponent child){
        childComponents.add(child);
}
    /**
     * 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
        childComponents.remove(index);
}
    /**
     * 聚集管理方法,返回所有子构件对象
*/
public List getChild(){
        return childComponents;
}

    /**
     * 输出对象的自身结构
* @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
*/
@Override
public void paycard(String preStr) {
        // 先把自己输出
System.out.println(preStr + "+" + this.name);
//如果还包含有子组件,那么就输出这些子组件对象
if(this.childComponents != null){
            //添加两个空格,表示向后缩进两个空格
preStr += "  ";
//输出当前对象的子对象
for(IComponent c : childComponents){
                //递归输出每个子对象
c.paycard(preStr);
}
        }
    }
}
public class Leaf implements IComponent {

    /**
     * 叶子对象的名字
*/
private String name;
/**
     * 构造方法,传入叶子对象的名称
* @param name 叶子对象的名字
*/
public Leaf(String name){
        this.name = name;
}
    /**
     * 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void paycard(String preStr) {
        // TODO Auto-generated method stub
System.out.println(preStr + "-" + name);
}

}
public interface IComponent {
    /**
     * 输出组建自身的名称
*/
public void paycard(String preStr);

}


总结:

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


实例和场景分析:


  那么我们就根据我们会员卡的消费,来模拟一下组合模式的实现吧!let's go!

        首先:

               1.我们的部件有,总店,分店,加盟店!

               2.我们的部件共有的行为是:刷会员卡

               3.部件之间的层次关系,也就是店面的层次关系是,总店下有分店、分店下可以拥有加盟店。

        有了我们这几个必要条件后,我的要求就是目前店面搞活动当我在总店刷卡后,就可以累积相当于在所有下级店面刷卡的积分总额,设计的代码如下:


这样在累积所有子店面积分的时候,就不需要去关心子店面的个数了,也不用关系是否是叶子节点还是组合节点了,也就是说不管是总店刷卡,还是加盟店刷卡,都可以正确有效的计算出活动积分。

public void testMarket(){
    MarketBranch rootMarket=new MarketBranch("总店");
MarketBranch shenBranch=new MarketBranch("深圳分店");

MarketJoin marketJoin1=new MarketJoin("深圳南山加盟店");
MarketJoin marketJoin2=new MarketJoin("深圳福田加盟店");

rootMarket.add(shenBranch);

shenBranch.add(marketJoin1);
shenBranch.add(marketJoin2);

rootMarket.PayByCard();

}
public class MarketBranch extends Market {

    public MarketBranch(String name){
        this.name=name;
}

    // 加盟店列表
List list = new ArrayList();

@Override
public void add(Market m) {
        list.add(m);
}

    @Override
public void remove(Market m) {
        list.remove(m);
}

    // 消费之后,该分店下的加盟店自动累加积分
@Override
public void PayByCard() {
        System.out.println(name + "消费,积分已累加入该会员卡");
        for (Market m : list) {
            m.PayByCard();
}
    }
}
/**
 * Created by Administrator on 2017/9/14.
 * 加盟店
*/

public class MarketJoin extends Market{


    public MarketJoin(String name){
        this.name=name;
}


    @Override
public void add(Market m) {

    }

    @Override
public void remove(Market m) {

    }

    @Override
public void PayByCard() {

    }

}
/**
 * Created by Administrator on 2017/9/14.
 * */

public abstract class Market {

    String name;

    public abstract void add(Market m);

    public abstract void remove(Market m);

    public abstract void PayByCard();
}


形象比喻:

COMPOSITE—Mary今天过生日。“我过生日,你要送我一件礼物。”

“嗯,好吧,去商店,你自己挑。”

“这件T恤挺漂亮,买,

这条裙子好看,买,

这个包也不错,买。”“

喂,买了三件了呀,我只答应送一件礼物的哦。”

“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。 

”“……”,MM都会用Composite模式了,你会了没有?


View和ViewGroup类的使用。在android UI设计,几乎所有的widget和布局类都依靠这两个类。

ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的

可见,作为容器的ViewGroup可以包含作为叶子节点的View

也可以包含作为更低层次的子ViewGroup

而子ViewGroup又可以包含下一层的叶子节点的View和ViewGroup


那就是View和ViewGroup类的使用。在android UI设计,几乎所有的widget和布局类都依靠这两个类。


1.意图
将对象View和ViewGroup组合成树形结构以表示"部分-整体"的层次结构(View可以做为ViewGroup的一部分)。
组合模式使得用户对单个对象View和组合对象ViewGroup的使用具有一致性。
热点词汇: 部分-整体 容器-内容 树形结构 一致性 叶子 合成 安全性 透明性


我们选择安全式的组合模式(在组合对象中添加add,remove,getChild方法),


public abstract class ViewGroup extends View implements ViewParent, ViewManager {
    private static final String TAG = "ViewGroup";

    private static final boolean DBG = false;
/** @hide */
public static boolean DEBUG_DRAW = false;

public void addView(View child, int index) {
    if (child == null) {
        throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
    LayoutParams params = child.getLayoutParams();
    if (params == null) {
        params = generateDefaultLayoutParams();
        if (params == null) {
            throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
    }
    addView(child, index, params);
}
public View getChildAt(int index) {
    if (index < 0 || index >= mChildrenCount) {
        return null;
}
    return mChildren[index];
}

ViewManager:

public interface ViewManager
{
    /**
     * Assign the passed LayoutParams to the passed View and add the view to the window.
     * 

Throws {@link android.view.WindowManager.BadTokenException} for certain programming * errors, such as adding a second view to a window without removing the first view. *

Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a * secondary {@link Display} and the specified display can't be found * (see {@link android.app.Presentation}). * @param view The view to be added to this window. * @param params The LayoutParams to assign to view. */ public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); }

用的场合

1.ViewPager:添加和移除:一个容器

2.悬浮窗:添加和移除

3.数据库:增删改查


代码和demo:不知道为什么上传不上去


参考博客:

http://blog.csdn.net/hp910315/article/details/51111478

你可能感兴趣的:(设计模式)