内容简介:它属于
目的
它属于 structural 设计模式目录。 将对象组合成树结构以表示部分整体层次结构。Composite允许客户端统一处理单个对象和对象组合。
解释
现实世界的例子
每个句子都由单词组成,而单词又由字符组成。这些对象中的每一个都是可打印的,并且它们可以在它们之前或之后打印一些东西,例如句子总是以句号结束并且字总是在它之前有空格。
简单来说
复合模式允许客户以统一的方式处理单个对象。
维基百科说
在软件工程中,复合模式是一种分区设计模式。复合模式描述一组对象将以与单个对象实例相同的方式进行处理。组合的目的是将对象“组合”到树结构中,以表示 部分— 整体 层次结构。通过实现复合模式,客户可以统一处理单个对象和组合。
结构
参与者
1.组件Component
- 声明组合中对象的接口。
- 根据需要,为所有类共有的接口实现默认行为。
- 声明用于访问和管理其子组件的接口。
- (可选)在递归结构中定义用于访问组件父级的接口,并在适当的情况下实现它。。
2.叶子 Leaf
- 表示组合中的叶子对象。叶子没有子类。
- 定义合成中基本对象的行为。
3.组合Composite
- 定义具有子项的组件的行为。
- 存储子组件。
- 在Component接口中实现与子相关的操作。
4.客户端Client
- 通过Component 接口操作组合中的对象 。
合作
- 客户端使用Component类接口与组合结构中的对象进行交互。如果收件人是Leaf,则直接处理请求。如果收件人是Composite,则它通常将请求转发给其子组件,可能在转发之前和/或之后执行其他操作。
源代码(示例1)
以我们上面的句子为例。这里有基类和不同的可打印类型
<b>public</b> <b>abstract</b> <b>class</b> LetterComposite {
<b>private</b> List<LetterComposite> children = <b>new</b> ArrayList<>();
<b>public</b> <b>void</b> add(LetterComposite letter) {
children.add(letter);
}
<b>public</b> <b>int</b> count() {
<b>return</b> children.size();
}
<b>protected</b> <b>void</b> printThisBefore() {}
<b>protected</b> <b>void</b> printThisAfter() {}
<b>public</b> <b>void</b> print() {
printThisBefore();
<b>for</b> (LetterComposite letter : children) {
letter.print();
}
printThisAfter();
}
}
<b>public</b> <b>class</b> Letter <b>extends</b> LetterComposite {
<b>private</b> <b>char</b> c;
<b>public</b> Letter(<b>char</b> c) {
<b>this</b>.c = c;
}
@Override
<b>protected</b> <b>void</b> printThisBefore() {
System.out.print(c);
}
}
<b>public</b> <b>class</b> Word <b>extends</b> LetterComposite {
<b>public</b> Word(List<Letter> letters) {
<b>for</b> (Letter l : letters) {
<b>this</b>.add(l);
}
}
@Override
<b>protected</b> <b>void</b> printThisBefore() {
System.out.print(<font>" "</font><font>);
}
}
<b>public</b> <b>class</b> Sentence <b>extends</b> LetterComposite {
<b>public</b> Sentence(List<Word> words) {
<b>for</b> (Word w : words) {
<b>this</b>.add(w);
}
}
@Override
<b>protected</b> <b>void</b> printThisAfter() {
System.out.print(</font><font>"."</font><font>);
}
}
</font>
然后我们有一个信使来传递信息
<b>public</b> <b>class</b> Messenger {
LetterComposite messageFromOrcs() {
List<Word> words = <b>new</b> ArrayList<>();
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('W'), <b>new</b> Letter('h'), <b>new</b> Letter('e'), <b>new</b> Letter('r'), <b>new</b> Letter('e'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('t'), <b>new</b> Letter('h'), <b>new</b> Letter('e'), <b>new</b> Letter('r'), <b>new</b> Letter('e'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('i'), <b>new</b> Letter('s'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('a'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('w'), <b>new</b> Letter('h'), <b>new</b> Letter('i'), <b>new</b> Letter('p'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('t'), <b>new</b> Letter('h'), <b>new</b> Letter('e'), <b>new</b> Letter('r'), <b>new</b> Letter('e'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('i'), <b>new</b> Letter('s'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('a'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('w'), <b>new</b> Letter('a'), <b>new</b> Letter('y'))));
<b>return</b> <b>new</b> Sentence(words);
}
LetterComposite messageFromElves() {
List<Word> words = <b>new</b> ArrayList<>();
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('M'), <b>new</b> Letter('u'), <b>new</b> Letter('c'), <b>new</b> Letter('h'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('w'), <b>new</b> Letter('i'), <b>new</b> Letter('n'), <b>new</b> Letter('d'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('p'), <b>new</b> Letter('o'), <b>new</b> Letter('u'), <b>new</b> Letter('r'), <b>new</b> Letter('s'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('f'), <b>new</b> Letter('r'), <b>new</b> Letter('o'), <b>new</b> Letter('m'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('y'), <b>new</b> Letter('o'), <b>new</b> Letter('u'), <b>new</b> Letter('r'))));
words.add(<b>new</b> Word(Arrays.asList(<b>new</b> Letter('m'), <b>new</b> Letter('o'), <b>new</b> Letter('u'), <b>new</b> Letter('t'), <b>new</b> Letter('h'))));
<b>return</b> <b>new</b> Sentence(words);
}
}
然后它可以用作
LetterComposite orcMessage = <b>new</b> Messenger().messageFromOrcs(); orcMessage.print(); <font><i>// Where there is a whip there is a way.</i></font><font> LetterComposite elfMessage = <b>new</b> Messenger().messageFromElves(); elfMessage.print(); </font><font><i>// Much wind pours from your mouth.</i></font><font> </font>
源代码(例2)
步骤1: 创建 将被视为组件 Component 的 Employee 接口 。
/ <b>this</b> is the Employee <b>interface</b> i.e. Component.
<b>public</b> <b>interface</b> Employee {
<b>public</b> <b>int</b> getId();
<b>public</b> String getName();
<b>public</b> <b>double</b> getSalary();
<b>public</b> <b>void</b> print();
<b>public</b> <b>void</b> add(Employee employee);
<b>public</b> <b>void</b> remove(Employee employee);
<b>public</b> Employee getChild(<b>int</b> i);
}<font><i>// End of the Employee interface. </i></font><font>
</font>
第2步: 创建一个 将被视为 Composite 的 BankManager 类, 并实现Employee接口。
<font><i>// this is the BankManager class i.e. Composite. </i></font><font>
<b>import</b> java.util.ArrayList;
<b>import</b> java.util.Iterator;
<b>import</b> java.util.List;
<b>public</b> <b>class</b> BankManager implements Employee {
<b>private</b> <b>int</b> id;
<b>private</b> String name;
<b>private</b> <b>double</b> salary;
<b>public</b> BankManager(<b>int</b> id,String name,<b>double</b> salary) {
<b>this</b>.id=id;
<b>this</b>.name = name;
<b>this</b>.salary = salary;
}
List<Employee> employees = <b>new</b> ArrayList<Employee>();
@Override
<b>public</b> <b>void</b> add(Employee employee) {
employees.add(employee);
}
@Override
<b>public</b> Employee getChild(<b>int</b> i) {
<b>return</b> employees.get(i);
}
@Override
<b>public</b> <b>void</b> remove(Employee employee) {
employees.remove(employee);
}
@Override
<b>public</b> <b>int</b> getId() {
<b>return</b> id;
}
@Override
<b>public</b> String getName() {
<b>return</b> name;
}
@Override
<b>public</b> <b>double</b> getSalary() {
<b>return</b> salary;
}
@Override
<b>public</b> <b>void</b> print() {
System.out.println(</font><font>"=========================="</font><font>);
System.out.println(</font><font>"Id ="</font><font>+getId());
System.out.println(</font><font>"Name ="</font><font>+getName());
System.out.println(</font><font>"Salary ="</font><font>+getSalary());
System.out.println(</font><font>"=========================="</font><font>);
Iterator<Employee> it = employees.iterator();
<b>while</b>(it.hasNext()) {
Employee employee = it.next();
employee.print();
}
}
}</font><font><i>// End of the BankManager class. </i></font><font>
</font>
第3步: 创建一个 将被视为叶子 leaf 的 Cashier 类, 它将实现到Employee接口。
<b>public</b> <b>class</b> Cashier implements Employee{
<font><i>/*
In this class,there are many methods which are not applicable to cashier because
it is a leaf node.
*/</i></font><font>
<b>private</b> <b>int</b> id;
<b>private</b> String name;
<b>private</b> <b>double</b> salary;
<b>public</b> Cashier(<b>int</b> id,String name,<b>double</b> salary) {
<b>this</b>.id=id;
<b>this</b>.name = name;
<b>this</b>.salary = salary;
}
@Override
<b>public</b> <b>void</b> add(Employee employee) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
}
@Override
<b>public</b> Employee getChild(<b>int</b> i) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
<b>return</b> <b>null</b>;
}
@Override
<b>public</b> <b>int</b> getId() {
</font><font><i>// TODO Auto-generated method stub </i></font><font>
<b>return</b> id;
}
@Override
<b>public</b> String getName() {
<b>return</b> name;
}
@Override
<b>public</b> <b>double</b> getSalary() {
<b>return</b> salary;
}
@Override
<b>public</b> <b>void</b> print() {
System.out.println(</font><font>"=========================="</font><font>);
System.out.println(</font><font>"Id ="</font><font>+getId());
System.out.println(</font><font>"Name ="</font><font>+getName());
System.out.println(</font><font>"Salary ="</font><font>+getSalary());
System.out.println(</font><font>"=========================="</font><font>);
}
@Override
<b>public</b> <b>void</b> remove(Employee employee) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
}
}
</font>
第4步: 创建一个 Accountant 类,它也将被视为一个 leaf ,它将实现到Employee接口。
<b>public</b> <b>class</b> Accountant implements Employee{
<font><i>/*
In this class,there are many methods which are not applicable to cashier because
it is a leaf node.
*/</i></font><font>
<b>private</b> <b>int</b> id;
<b>private</b> String name;
<b>private</b> <b>double</b> salary;
<b>public</b> Accountant(<b>int</b> id,String name,<b>double</b> salary) {
<b>this</b>.id=id;
<b>this</b>.name = name;
<b>this</b>.salary = salary;
}
@Override
<b>public</b> <b>void</b> add(Employee employee) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
}
@Override
<b>public</b> Employee getChild(<b>int</b> i) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
<b>return</b> <b>null</b>;
}
@Override
<b>public</b> <b>int</b> getId() {
</font><font><i>// TODO Auto-generated method stub </i></font><font>
<b>return</b> id;
}
@Override
<b>public</b> String getName() {
<b>return</b> name;
}
@Override
<b>public</b> <b>double</b> getSalary() {
<b>return</b> salary;
}
@Override
<b>public</b> <b>void</b> print() {
System.out.println(</font><font>"========================="</font><font>);
System.out.println(</font><font>"Id ="</font><font>+getId());
System.out.println(</font><font>"Name ="</font><font>+getName());
System.out.println(</font><font>"Salary ="</font><font>+getSalary());
System.out.println(</font><font>"========================="</font><font>);
}
@Override
<b>public</b> <b>void</b> remove(Employee employee) {
</font><font><i>//this is leaf node so this method is not applicable to this class. </i></font><font>
}
}
</font>
步骤5: 创建一个 CompositePatternDemo 类,该类也将被视为 客户端 Client ,ii将使用Employee接口。
<b>public</b> <b>class</b> CompositePatternDemo {
<b>public</b> <b>static</b> <b>void</b> main(String args[]){
Employee emp1=<b>new</b> Cashier(101,<font>"Sohan Kumar"</font><font>, 20000.0);
Employee emp2=<b>new</b> Cashier(102,</font><font>"Mohan Kumar"</font><font>, 25000.0);
Employee emp3=<b>new</b> Accountant(103,</font><font>"Seema Mahiwal"</font><font>, 30000.0);
Employee manager1=<b>new</b> BankManager(100,</font><font>"Ashwani Rajput"</font><font>,100000.0);
manager1.add(emp1);
manager1.add(emp2);
manager1.add(emp3);
manager1.print();
}
}
</font>
适用性
使用复合模式时
- 您想要表示对象的 部分— 整体 层次结构
- 您希望客户能够忽略对象组合和单个对象之间的差异。客户端将统一处理复合结构中的所有对象
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Java中的复合视图设计模式(Composite View Design Pattern)
- MongoDB指南---10、索引、复合索引 简介
- 为什么要有复合索引?
- python – Django或类似的复合主键
- GO的第五天,复合数据类型---数组、Slice
- Redis进阶应用:Redis+Lua脚本实现复合操作
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
风吹江南之互联网金融
陈宇(江南愤青) / 东方出版社 / 2014-6-1 / 55元
随着中国互联网金融浪潮高涨,P2P、众筹、余额宝、微信支付等新生事物层出不穷,加之大数据等时髦概念助阵,简直是乱花渐欲迷人眼,令媒体兴奋,公众狂热。那么,互联网金融真的能“颠覆”传统金融吗?当互联网思维对撞传统金融观念,是互联网金融的一统天下,还是传统金融业的自我革新?究竟是谁动了金融业的奶酪? 本书作者早期试水创立具有互联网金融雏形的网站,后来成为互联网金融的资深投资人,基于其多年在该领域......一起来看看 《风吹江南之互联网金融》 这本书的介绍吧!
正则表达式在线测试
正则表达式在线测试
HEX HSV 转换工具
HEX HSV 互换工具