组合模式( Composite),将对象组合成树形结构以表示‘部分整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式类似于数据结构中的树形结构,如果某个对象可以由多个同类对象组合形成,那么他们之间就形成了一个数形结构,比如多级菜单:
组合模式包含三类角色:
组合模式有两种不同的具体实现,分别为
一个评论系统,某条评论可以设置允许回复和不允许回复,不允许回复的评论对象可以看作Leaf,允许回复的评论可以看作Composite
package pers.junebao.composite_pattern.demo;
/**
* @author Junebao
*/
public interface InterComment {
/**
* 展示评论
*/
void showComment();
/**
* 回复评论
* @param comment: 回复的 InterComment 对象
*/
void reply(InterComment comment);
}
package pers.junebao.composite_pattern.demo;
import java.util.ArrayList;
/**
* @author JuneBao
* @date 2020/6/27 23:13
*/
public class CanReplyComment implements InterComment {
private String content;
private String date;
private ArrayList<InterComment> comments = new ArrayList<>();
public CanReplyComment(String str, String date) {
this.content = str;
this.date = date;
}
@Override
public void showComment() {
System.out.println(this.content + "(" + this.date + ")");
System.out.print(" ");
for (InterComment comment : comments) {
comment.showComment();
}
}
@Override
public void reply(InterComment comment) {
comments.add(comment);
}
}
package pers.junebao.composite_pattern.demo;
/**
* @author JuneBao
* @date 2020/6/27 23:20
*/
public class BanReplyComment implements InterComment {
private String content;
private String date;
public BanReplyComment(String str, String date){
this.content = str;
this.date = date;
}
@Override
public void showComment() {
System.out.println(this.content + "(" + this.date + ")");
}
@Override
public void reply(InterComment comment) {
System.err.println("This comment is not allowed to reply");
}
}
package pers.junebao.composite_pattern.demo;
/**
* @author JuneBao
* @date 2020/6/27 23:23
*/
public class Client {
public static void main(String[] args) {
InterComment firstComment = new CanReplyComment("This comment allows reply", "2020-6-20");
InterComment canReply = new CanReplyComment("This reply can reply", "2020-6-23");
firstComment.reply(canReply);
InterComment banReply = new BanReplyComment("This reply can not reply", "2020-6-24");
firstComment.reply(banReply);
InterComment canReply2 = new CanReplyComment("I can reply", "2020-6-24");
canReply.reply(canReply2);
banReply.reply(canReply2);
firstComment.showComment();
InterComment secondComment = new BanReplyComment("This comment can not reply", "2020-6-27");
secondComment.reply(new CanReplyComment("xxx", "2020-6-27"));
secondComment.showComment();
}
}