一.内容说明
某教育机构组织结构如下图所示:
在该教育机构的OA系统中可以给各级办公室下发公文,试采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。
二.设计类图
三.全部类代码
package compositepattern;
public abstract class AbstractBranch {
public abstract void receiveDoc();
public abstract String getName();
public void setName(String name) {}
}
public class AdOffice extends AbstractBranch{
private String name;
public void receiveDoc() {
System.out.println("行政办公室收到文件");
}
public AdOffice(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class EdOffice extends AbstractBranch{
private String name;
public void receiveDoc() {
System.out.println("教务办公室收到文件");
}
public EdOffice(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
import java.util.ArrayList;
public class Branch extends AbstractBranch{
private ArrayList<AbstractBranch>list;
private String name;
public Branch(String name) {
this.name = name;
}
public void receiveDoc() {
System.out.println(name+"收到文件");
}
public AbstractBranch getChild(int n) {
return list.get(n);
}
public void add(AbstractBranch abBranch) {
list.add(abBranch);
}
public void remove(AbstractBranch abBranch) {
list.remove(abBranch);
}
public String getName() {
return name;
}
public void sendDoc(AbstractBranch abBranch) {
System.out.println(name+ "发送文件到"+abBranch.getName());
abBranch.receiveDoc();
}
}
首先设计一个AbstractBranch类,用于访问和管理子部件,里面有两个抽象方法ReceiveDoc()和getName(),然后设计两个子类AdOffice,EdOffice去实现父类的方法,其次再设计一个有枝结点类Branch继承AbstractBranch类,里面不但包含实现父类的方法,而且有增加和删除结点的add()和remove()方法。最后设计一个XMLUilt类去获取.xml配置文件中的具体类名并返回一个实例对象。
客户类:
public class Client {
public static void main(String[] args) {
AbstractBranch ab1 = (AbstractBranch) XMLUtil.getBean();
ab1.setName("行政办公室");
AbstractBranch ab2 = (AbstractBranch) XMLUtil.getBean();
ab2.setName("教务办公室");
Branch b1 = (Branch)XMLUtil.getBean();
b1.setName("北京总部");
Branch b2 = (Branch)XMLUtil.getBean();
b2.setName("湖南分校");
Branch b3 = (Branch)XMLUtil.getBean();
b3.setName("长沙教学点");
Branch b4 = (Branch)XMLUtil.getBean();
b4.setName("湘潭教学点");
b1.sendDoc(b2);
b2.sendDoc(b3);
b2.sendDoc(b4);
b3.sendDoc(ab1);
b4.sendDoc(ab2);
}
XMLUtil类:
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class XMLUtil {
//该方法用于配置从XML配置文件中提取具体类名,并返回一个实例对象
public static Object getBean() {
try {
//创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src/compositepattern/NewFile.xml"));
//获取包含类名的文本节点
NodeList n1 = doc.getElementsByTagName("className");
Node classNode = n1.item(0).getFirstChild();
String cName = classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
xml配置文件:
<?xml version="1.0"?>
<config>
<className>compositepattern.Branch</className>
</config>
四.运行结果
五.分析和总结
1.整体构造:
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
2.优点:
(1) 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。
(2)客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。
(3)定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。
(4)更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。
3.缺点:
使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。