今天要说的是结构模式的最后一个,组合模式。
他和我们的数据结构里面的树有点关系,怎么个关系?
还记得我们在讲 设计模式4---对外包办的门面模型
的案例提到的老板叫总经理干活,实际是下面别的部门的人在干活的案例吗?
现在我们来写一个基于组合模型的总经理叫各部门人员干活的过程。
代码实现
我们定义下基础的抽象类
public abstract class Component {
private String name;
private String position;
public abstract void operation();
public Component(String name, String position) {
this.name = name;
this.position = position;
}
public String getName() {
return name;
}
public String getPosition() {
return position;
}
}
我们先抽象出一个组建类,这个是基础,我们的总有个名字和部门,同时还要干活operation
吧。
我们看下我们的部门类:
public class BranchComponent extends Component {
private List<Component> componentList = new ArrayList<>();
public BranchComponent(String name, String position) {
super(name, position);
}
@Override
public void operation() {
System.out.print(this.getPosition() + "部门都在干活");
}
public void addComponent(Component component) {
componentList.add(component);
}
public void removeComponent(Component component) {
componentList.remove(component);
}
public List<Component> getComponentList() {
return componentList;
}
}
部门当然要有员工在里面啦,所以我们有一个componentList
来保存员工信息,同时配套一些函数来增加员工addComponent
,开除偷懒的removeComponent
。
接着看下我们的员工类
public class LeafComponent extends Component {
public LeafComponent(String name, String position) {
super(name, position);
}
@Override
public void operation() {
System.out.println("部门"+this.getPosition()+ "员工"+this.getName()+" 正在干活");
}
}
他的内容就是干活,没什么好好说的。
但不一样的是,我们的员工是树的”叶子
“,所以他没别的了,不能添加内容,不像部门是一个”分支点”,可以加内容。
有了这些准备我们可以来写测试的情况了
相对平常的有点长,因为要生成一些mock的数据。
public class Boss {
public static void main(String[] args) {
BranchComponent manager = getBranchTree();
orderToOperation(manager);
}
private static void orderToOperation(BranchComponent manager) {
List<Component> componentList = manager.getComponentList();
for (Component component : componentList) {
if (component instanceof LeafComponent) {
component.operation();
} else {
orderToOperation((BranchComponent) component);
}
}
}
private static BranchComponent getBranchTree() {
BranchComponent manager = new BranchComponent("总经理", "总裁办");
BranchComponent sales = new BranchComponent("销售负责人", "销售部");
BranchComponent product = new BranchComponent("开发负责人", "产品部");
LeafComponent pA = new LeafComponent("开发a", "开发人员");
LeafComponent pB = new LeafComponent("开发b", "开发人员");
LeafComponent pC = new LeafComponent("开发c", "开发人员");
LeafComponent sA = new LeafComponent("销售a", "销售人员");
LeafComponent sB = new LeafComponent("销售a", "销售人员");
LeafComponent sC = new LeafComponent("销售a", "销售人员");
manager.addComponent(sales);
manager.addComponent(product);
sales.addComponent(sA);
sales.addComponent(sB);
sales.addComponent(sC);
product.addComponent(pA);
product.addComponent(pB);
product.addComponent(pC);
return manager;
}
}
是不是和我们学数据结构里面的树一样?现在是在遍历二叉树的感觉?
类图
这个就是我们的UML类图,不过有一点要提的是,这个是叫透明模式
,因为他把我们部门的加人和赶人的方法都加上去了。我们在调用这些子类的时候,都可以看到,所以叫透明模式。
如果把这几个函数移回到我们的BranchComponent
去的话,就叫安全模式
。他避免我们在访问的时候,如果是叶节点的时候,不会访问到这几个函数,因此安全。
当然这连个模式各有优缺,可以自己权衡。
这个组合模式的一个缺点的是,我们在使用的时候需要直接用实现类,而不是接口!
BranchComponent manager = new BranchComponent("总经理", "总裁办");
LeafComponent sC = new LeafComponent("销售a", "销售人员");
这对于习惯强调面向接口编程
上来说是不好的,需要我们自己权衡。
后记
今天没有后记。