您的位置:首页 > 职场人生

设计模式(十)组合模式

2018-03-29 22:24 288 查看
版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112

目录

目录

导航

前言

例子

总结
优点

缺点

Git地址

导航

设计模式之六大设计原则

设计模式(一)单例模式

设计模式(二)工厂模式

设计模式(三)策略模式

设计模式(四)适配器模式

设计模式(五)享元模式

设计模式(六)建造者模式

设计模式(七)原型模式

设计模式(八)桥接模式

设计模式(九)外观模式

前言

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

其实可以相信成数据结构中的树型结构一样,他们有公有的方法和属性,而父节点有自己特有的方法和属性。

例子

LZ就构造一颗树来说明这个问题,和树不一样的是,这个的叶子节点永远是叶子节点,他和父节点是不同的对象。

/***
*
*@Author ChenjunWang
*@Description:公共的抽象类
*@Date: Created in 21:27 2018/3/29
*@Modified By:
*
*/
public abstract class Component {
int val;//所有节点都有值
public abstract void add(Component component);
public abstract void remove(Component component);

public abstract void show();

}

/***
*
*@Author ChenjunWang
*@Description:父节点类
*@Date: Created in 21:36 2018/3/29
*@Modified By:
*
*/
public class Composite extends Component{
List<Component> list = new ArrayList<>();//有一个列表来包涵它的子节点

public Composite(int val){
this.val = val;//构造函数
}

@Override
public void add(Component component) {
list.add(component);//往列表中加节点

}

@Override
public void remove(Component component) {

list.remove(component);//删列表中的该节点
}

@Override
public void show() {

System.out.println(val);//若是父节点则输出值并遍历出她所有的子节点的值
for (Component c : list){
c.show();
}

}
}

/***
*
*@Author ChenjunWang
*@Description:叶子节点类
*@Date: Created in 21:35 2018/3/29
*@Modified By:
*
*/
public class Leaf extends Component{

public Leaf(int val){
this.val = val;//构造函数
}

@Override
public void add(Component component) {
//因为叶子节点不能添加,所有为空
}

@Override
public void remove(Component component) {
//不能删除,为空
}

@Override
public void show() {

//输出值
System.out.println(val);
}
}

/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 21:42 2018/3/29
*@Modified By:
*
*/
public class Test {

public static void main(String[] args) {
Component composite1 = new Composite(1);
Component composite2 = new Composite(12);
Component composite3 = new Composite(23);
Component leaf = new Leaf(34);
composite1.add(composite2);
composite2.add(composite3);
composite3.add(leaf);
System.out.println("从父节点1开始show");
composite1.show();
System.out.println("从父节点3开始show");
composite3.show();

}
}
输出结果如下
---------------------------
从父节点1开始show
1
12
23
34
从父节点3开始show
23
34


UML图



上面就是一个组合模式的实际应用,我们会发现,有一个问题,那就是子节点也有add和remove方法,但是实际上,它应该是不允许访问这方法的,不符合接口隔离原则。所以上面的为不安全的组合模式。那如何做到安全呢,

/***
*
*@Author ChenjunWang
*@Description:公共的抽象类
*@Date: Created in 21:27 2018/3/29
*@Modified By:
*
*/
public abstract class Component {
int val;//所有节点都有值

public abstract void show();

}

/***
*
*@Author ChenjunWang
*@Description:父节点类
*@Date: Created in 21:36 2018/3/29
*@Modified By:
*
*/
public class Composite extends Component{
List<Component> list = new ArrayList<>();//有一个列表来包涵它的子节点

public Composite(int val){
this.val = val;//构造函数
}

public void add(Component component) {
list.add(component);//往列表中加节点

}

public void remove(Component component) {

list.remove(component);//删列表中的该节点
}

@Override
public void show() {

System.out.println(val);//若是父节点则输出值并遍历出她所有的子节点的值
for (Component c : list){
c.show();
}

}
}

/***
*
*@Author ChenjunWang
*@Description:叶子节点类
*@Date: Created in 21:35 2018/3/29
*@Modified By:
*
*/
public class Leaf extends Component{

public Leaf(int val){
this.val = val;//构造函数
}

@Override
public void show() {

//输出值
System.out.println(val);
}
}

/***
*
*@Author ChenjunWang
*@Description:
*@Date: Created in 21:42 2018/3/29
*@Modified By:
*
*/
public class Test {

public static void main(String[] args) {
Composite composite1 = new Composite(1);
Composite composite2 = new Composite(12);
Composite composite3 = new Composite(23);
Component leaf = new Leaf(34);
composite1.add(composite2);
composite2.add(composite3);
composite3.add(leaf);
System.out.println("从父节点1开始show");
composite1.show();
System.out.println("从父节点3开始show");
composite3.show();

}
}
输出结果如下
---------------------------
从父节点1开始show
1
12
23
34
从父节点3开始show
23
34


这样就是安全组合模式了,子节点不再能调用到父节点的独有的方法,但是对于调用的人来说,他在使用中,不再能已抽象类声明了。

总结

优点

(1)组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器,将”客户代码与复杂的对象容器结构“解耦。

(2)更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,有利于系统的拓展和维护。

缺点

(1) 若使用安全的组合模式,得直接申明实现类,这在面向接口编程上是很不恰当的,与依赖倒置原则冲突。若使用不安全的组合模式,则违反接口隔离原则。

(2)使你的系统结构更加复杂。

Git地址

本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/composite

回到最上方

有什么不懂或者不对的地方,欢迎留言。

喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。

觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息