结构型模式之——组合模式

结构型模式之 组合模式

前言

对于树形结构,在代码中有容器节点和叶子节点之分,容器节点可以有子节点,而叶子节点没有,所以两者是有区分的,而在实际使用中,我们更希望一致的对待他们,因为如若区别对待,在程序上会非常复杂。组合模式则是为了解决此类问题而生的,它可以让叶子对象和容器对象的使用具有一致性。他是组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构,故称为组合模式(这个是我猜的……)。


模式定义

组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。
在组合模式中引入了抽象构件类Component,它是所有容器类和叶子类的公共父类,客户端针对Component进行编程。


模式结构

Component 抽象构件,叶子构件和容器构件的接口或抽象类

Leaf 叶子构件,叶子节点没有子节点

Composite 容器构件,容器节点可以有子节点,子节点也可以是容
器构件。


UML类图


适用场景

在以下情况下可以使用组合模式:

1 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
2 在一个使用面向对象语言开发的系统中需要处理一个树形结构。
3 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

看看大神怎么用

组合模式使用面向对象的思想来实现树形结构的构建与处理,描述了如何将容器对象和叶子对象进行递归组合,实现简单,灵活性好。由于在软件开发中存在大量的树形结构,因此组合模式是一种使用频率较高的结构型设计模式,Java SE中的AWT和Swing包的设计就基于组合模式,在这些界面包中为用户提供了大量的容器构件(如Container)和成员构件(如Checkbox、Button和TextComponent等)


高清有码

前戏:我们就Android的UI做一个简单的例子,界面控件分为两大类:View和ViewGroup。View是单元控件,如TextView,ImageView。ViewGroup是容器节点,如LinearLayout…我们用组合模式来设计这个库。
正文开始,未满18岁的可以离场了。

Demo角色预览:

AbstractView 控件节点接口

ViewGroup 容器节点父类

View 子节点父类

LinearLayout 父节点实现类

RelativeLayout 父节点实现类

TextVeiw 子节点实现类

ImageView 子节点实现类

AbstractView

/**
 * 控件抽象类
 * Created by R on 2016/8/17.
 */
public interface AbstractView {

    void addView(AbstractView view);

    void removeView(AbstractView view);

    void show();

}

View

/**
 * 子控件的父类
 * Created by R on 2016/8/18.
 */
public abstract class View implements AbstractView{

    String id;

    public View(String id){
        this.id = id;
    }

    @Override
    public void addView(AbstractView view) {
        System.out.println("该控件不支持此方法");
    }

    @Override
    public void removeView(AbstractView view) {
        System.out.println("该控件不支持此方法");
    }

}

ViewGroup

/**
 * 容器控件的父类
 * Created by R on 2016/8/18.
 */
public abstract class ViewGroup implements AbstractView{

    String id;

    public ViewGroup(String id){
        this.id = id;
    }

    protected LinkedList<AbstractView> mChilds = new LinkedList<>();

    @Override
    public void addView(AbstractView view) {
        mChilds.add(view);
    }

    @Override
    public void removeView(AbstractView view) {
        mChilds.remove(view);
    }

}

LinearLayout

/**
 * Created by R on 2016/8/18.
 */
public class LinearLayout extends ViewGroup{

    public LinearLayout(String id) {
        super(id);
    }

    @Override
    public void show() {
        System.out.println("线性布局容器:" + id + " 显示");
        for (AbstractView mChild : mChilds) {
            mChild.show();
        }
    }
}

RelativeLayout

/**
 * Created by R on 2016/8/18.
 */
public class RelativeLayout extends ViewGroup{

    public RelativeLayout(String id) {
        super(id);
    }

    @Override
    public void show() {
        System.out.println("相对布局容器:" + id + " 显示");
        for (AbstractView mChild : mChilds) {
            mChild.show();
        }
    }
}

TextView

/**
 * Created by R on 2016/8/18.
 */
public class TextView extends View{

    public TextView(String id) {
        super(id);
    }

    @Override
    public void show() {
        System.out.println("文字控件:" + id + " 显示");
    }
}

ImageView

/**
 * Created by R on 2016/8/18.
 */
public class ImageView extends View{

    public ImageView(String id) {
        super(id);
    }

    @Override
    public void show() {
        System.out.println("图片控件:" + id + " 显示");
    }
}

Client 使用

/**
 * Created by R on 2016/8/17.
 */
public class Client {

    public void main(){
        AbstractView view1 , view2 , view3, view4 , view5 , view6 , viewGroupRoot, viewGroup2, viewGroup3;

        viewGroupRoot = new LinearLayout("根布局");
        viewGroup2 = new RelativeLayout("容器1");
        viewGroup3 = new LinearLayout("容器2");

        view1 = new TextView("文本1");
        view2 = new TextView("文本2");
        view3 = new TextView("文本3");
        view4 = new ImageView("图片1");
        view5 = new ImageView("图片2");
        view6 = new ImageView("图片3");

        viewGroupRoot.addView(view1);
        viewGroupRoot.addView(viewGroup2);
        viewGroupRoot.addView(viewGroup3);

        viewGroup2.addView(view2);
        viewGroup2.addView(view3);

        viewGroup3.addView(view4);
        viewGroup3.addView(view5);
        viewGroup3.addView(view6);

        viewGroup3.removeView(view6);

        viewGroupRoot.show();
    }
}

输出:

输出内容


总结

树形结构由容器节点和叶子节点组成,简单来说组合模式就是将容器节点和叶子节点转化为一种节点来使用的设计模式,这样一来便可将精力更专注于树的结构,而不是节点的类型上了。
据我不成熟的猜想,Android中的View系列就用到了组合模式,并且用的淋漓尽致。所有View都是节点,View就是View和ViewGroup的Component,只不过他不是抽象类或接口。而我们在构件界面的时候并不是特别关注节点的类型,而是节点之间的关系。并且在Touch事件中尤为明显,Touch事件可以针对某一个节点,也可以针对某一节点之下的所有节点。

感谢

跪在地上谢的站点-所有文章均参考这里

所有文章全部参考了这个网站

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计模式是一种经过总结、优化的、可重复使用的设计经验的总结。它是软件工程中一种解决特定问题的可复用方案。设计模式不是一成不变的,而是可以根据不同的需求进行变化,以达到最佳的效果。设计模式可以提高程序的可读性、可维护性、可扩展性,同时也可以提高程序的性能和稳定性。 设计模式可以分为三种类型:创建型模式、结构型模式和行为型模式。创建型模式用于描述对象的创建过程,结构型模式用于描述对象之间的关系,行为型模式用于描述对象的行为和交互。本篇文章将介绍一些常用的设计模式。 1. 工厂模式(Factory Pattern) 工厂模式是一种常用的创建型模式,它使用一个工厂方法来创建对象,而不是通过直接调用构造函数。工厂模式可以隐藏对象的创建过程,使代码更加灵活和易于维护。工厂模式可以分为简单工厂模式、工厂方法模式和抽象工厂模式。 2. 单例模式(Singleton Pattern) 单例模式是一种创建型模式,它保证一个类只有一个实例,并提供一个全局访问点。单例模式可以保证对象的唯一性,避免了多个实例对系统资源的浪费。 3. 代理模式(Proxy Pattern) 代理模式是一种结构型模式,它为一个对象提供一个代理,以控制对这个对象的访问。代理模式可以增加对象的安全性,降低对象的访问成本,同时也可以提高程序的灵活性和可扩展性。 4. 装饰器模式(Decorator Pattern) 装饰器模式是一种结构型模式,它动态地给一个对象添加一些额外的职责,而不需要修改这个对象的代码。装饰器模式可以避免使用子类来扩展对象的功能,从而使代码更加灵活和可扩展。 5. 观察者模式(Observer Pattern) 观察者模式是一种行为型模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生改变时,会通知所有的观察者对象,使它们能够及时更新自己的状态。 以上是五种常用的设计模式,它们在软件开发中都有着广泛的应用。设计模式可以帮助我们更好地组织代码、降低程序的耦合度、提高程序的可扩展性和可维护性,是一种非常重要的编程技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值