java设计模式-结构性模式-组合
主要应用于结构模型,比如html,xml这种结构比较鲜明的对象:
定义一个父子节点都要遵守的接口规范:
import java.util.List;
public interface Compent {
Compent add(Compent compent);
List<Compent> children();
String toXml();
Compent Remove(Compent compent);
}
规范中定义了4个方法;分别是实现增加,查询子节点,规范成为xml字体显示以及删除
然后定义相应的父子节点:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringJoiner;
public class Leaf implements Compent{
String name;
List<Compent> list = new ArrayList<>();
public Leaf(String name){
this.name =name;
}
@Override
public Compent add(Compent compent) {
list.add(compent);
return this;
}
@Override
public List<Compent> children() {
return list;
}
@Override
public String toXml() {
String start = "<"+this.name+">";
String end = "<\\"+this.name+">";
StringJoiner sj = new StringJoiner("",start,end);
list.forEach(compent -> sj.add(compent.toXml()));
return sj.toString();
}
@Override
public Compent Remove(Compent compent) {
Iterator<Compent> iter = list.iterator();
while(iter.hasNext()){
Compent com = iter.next();
if(com.toXml().equals(compent.toXml())){
iter.remove();
}
}
return this;
}
}
其中这里定义父节点,可以实现对子节点的操作,而且其中add和remove方法返回是本身,所以可以链式操作,
子节点定义:
import java.util.List;
import java.util.StringJoiner;
public class smaller implements Compent{
private String name;
private String text;
public smaller(String text){
this.name = "p";
this.text=text;
}
@Override
public Compent add(Compent compent) {
throw new UnsupportedOperationException();
}
@Override
public List<Compent> children() {
throw new UnsupportedOperationException();
}
@Override
public String toXml() {
String start = "<"+this.name+">";
String end = "<\\"+this.name+">";
StringJoiner sj = new StringJoiner("",start,end);
sj.add(this.text);
return sj.toString();
}
@Override
public Compent Remove(Compent compent) {
throw new UnsupportedOperationException();
}
}
子节点实现接口,缺点是会存在一些节点有空运行或者抛出错误
public class Test {
public static void main(String[] args) {
var root = new Leaf("company");
var s=root.add(
new smaller("hello")
).add(
new smaller("world")
).Remove(
new smaller("hello")
).add(
new smaller("hello")
).toXml();
System.out.println(s);
}
}
运行之后的结果:
可以取消接口的定义,或者接口只定义共有的方法,让子类去实现私有的方法