组合模式,到底是怎么组合的呢?在平时的编码中我们用的多不多呢?
组合模式(Composite Pattern),又叫部分整体模式,把一组相似的对象当成一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分与整体的层次。它是一种结构型模式。
业务场景:文件、文件夹构成的树形菜单,甚至公司里的组织结构,类似这样的场景都可以用组合模式表示。
UML类图关系如下:
叶子下面没有子组件,但是分支下面还可以有子分支,子分支下又有子分支,这便是组合模式。
实现代码的几个步骤。
步骤1,抽象组件;
/**
* 1.抽象组件类
* @author 程就人生
* @Date
*/
public abstract class AbstractComponent {
// 分支名称
private String name;
// 增加
public abstract void addChild(AbstractComponent compomnent);
// 删除
public abstract void removeChild(AbstractComponent compomnent);
// 获取子节点
public abstract List<AbstractComponent> getChild();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
步骤2,实现类;
/**
* 2.组件树枝的实现
* @author 程就人生
* @Date
*/
public class Branch extends AbstractComponent{
// 子组件
private List<AbstractComponent> componentList;
public Branch(String name) {
this.setName(name);
componentList = new ArrayList<>();
}
@Override
public void addChild(AbstractComponent compomnent){
componentList.add(compomnent);
}
@Override
public void removeChild(AbstractComponent compomnent){
componentList.remove(compomnent);
}
@Override
public List<AbstractComponent> getChild(){
return componentList;
}
}
import java.util.List;
/**
* 2.组件叶子的实现
* @author 程就人生
* @Date
*/
public class Leaf extends AbstractComponent{
public Leaf(String name) {
this.setName(name);
}
@Override
public List<AbstractComponent> getChild() {
return null;
}
@Override
public void addChild(AbstractComponent compomnent) {
return;
}
@Override
public void removeChild(AbstractComponent compomnent) {
return;
}
}
步骤3测试代码:
public static void main(String[] argo){
// 建立根节点
AbstractComponent root = new Branch("主干");
// 大树的第一个分支
AbstractComponent secBranch = new Branch("分支1");
AbstractComponent threeBranch = new Branch("分支11");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
threeBranch = new Branch("分支12");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
threeBranch = new Branch("分支13");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
threeBranch = new Branch("分支14");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
root.addChild(secBranch);
// 大树的第二个分支
secBranch = new Branch("分支2");
threeBranch = new Branch("分支21");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
threeBranch = new Branch("分支22");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
threeBranch = new Branch("分支23");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
root.addChild(secBranch);
// 大树的第三个分支
secBranch = new Branch("分支3");
threeBranch = new Branch("分支31");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
secBranch.addChild(threeBranch);
threeBranch = new Branch("分支32");
threeBranch.addChild(new Leaf("叶子"));
threeBranch.addChild(new Leaf("叶子"));
root.addChild(secBranch);
// 打印全部节点
printComponent(root,"");
}
// 打印组件
public static void printComponent(AbstractComponent component, String pre){
System.out.println(pre + component.getName());
if(component.getChild() != null){
for(AbstractComponent componentTemp : component.getChild()){
printComponent(componentTemp, "--" + pre);
}
}
}
打印结果:
主干
--分支1
----分支11
------叶子
------叶子
----分支12
------叶子
------叶子
----分支13
------叶子
------叶子
----分支14
------叶子
------叶子
--分支2
----分支21
------叶子
------叶子
----分支23
------叶子
------叶子
--分支3
----分支31
------叶子
------叶子
这段代码的意思:画一个大树,从主干画起,再添加枝干,枝干上最后添加叶子。
最后总结
组合模式在实际开发场景中用的还是蛮多的,多到很容易让人忽略它的存在。今天一看才恍然大悟,仔细研究一下,也不是太难。
同一个模式,有简单的实现,也有复杂的实现。上面的示例代码如果把抽象组件类、叶子类去掉,就是一个非常简单的组合模式。
模式不变,代码在变,关键代码没变。
网友评论