Composite Pattern - 组合模式 - java 实现

这篇文章将介绍另一个相对常用的设计模式:组合模式。

对于 组合模式 的使用场景,以及优缺点等说明,请参考 菜鸟教程|组合模式 ,这边文章里面已经说明的非常详细和清楚了。

这篇文章的例子增强了上一篇 Builder Pattern - 构建者模式 - java 实现 里面 HtmlWrapper 的功能。使他具有拼装子标签的能力,具体代码如下:

public class HtmlWrapper {
    private String tag;
    private String content;
    private String attrsInTag;

    // We don't want client side to initialize a `HtmlWrapper`, so we make the construct method as `private`
    private HtmlWrapper(Builder builder) {
        this.tag = builder.getTag();
        this.content = builder.getContent();
        this.attrsInTag = builder.getAttrsInTag();
    }

    // `Builder` is a common name in Builder Pattern, you can give a name what ever you want, but `Builder` is the best
    public static class Builder {
        private String tag;
        private String content;
        private String attrsInTag;

        private String getTag() {
            return tag;
        }

        public Builder setTag(String tag) {
            this.tag = tag;
            return this;
        }

        private String getContent() {
            return content;
        }

        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        private String getAttrsInTag() {
            return attrsInTag;
        }

        public Builder setAttrsInTag(String attrsInTag) {
            this.attrsInTag = attrsInTag;
            return this;
        }

        public HtmlWrapper build() {
            return new HtmlWrapper(this);
        }
    }

    // All sub tags would be hold by this `subTags`.
    private Collection subTags = new LinkedList();

    // Provide a way to let a sub tag to be appended to the current tag
    public void addSubTag(HtmlWrapper subTagContent) {
        if (subTagContent != null) {
            subTags.add(subTagContent);
        }
    }

    // Return all sub tags of current tag
    public Collection getSubTags() {
        return subTags;
    }

    private String getAttrsInTag() {
        return StringUtils.isBlank(this.attrsInTag) ? "" : " " + this.attrsInTag;
    }

    private String getTag() {
        return this.tag;
    }

    private String getStartTag() {
        if (StringUtils.isBlank(getTag())) {
            return "";
        }

        return new StringBuilder().append("<").append(getTag()).append(getAttrsInTag()).append(">").toString();
    }

    private String getEndTag() {
        if (StringUtils.isBlank(getTag())) {
            return "";
        }

        return new StringBuilder().append("").toString();
    }

    private String getContent() {
        if (StringUtils.isBlank(this.content)) {
            return "";
        }
        return this.content;
    }

    // Here we need to return a formatted HTML code to the client side, so we `override` this method
    public String toString() {
        return toString(0);
    }

    private String getIndent(int level) {
        int whitespaceNumber = 4 * level;
        StringBuilder indent = new StringBuilder();
        for (int i = 1; i <= whitespaceNumber; i++) {
            indent.append(" ");
        }
        return indent.toString();
    }

    // Here we use a recursive way to display current tag and its sub tags as a string
    private String toString(int level) {
        String lineBreak = "\n";
        StringBuilder tagsb = new StringBuilder();

        // start tag part
        if (StringUtils.isNotBlank(getTag())) {
            tagsb.append(getIndent(level)).append(getStartTag()).append(lineBreak);
        }

        // content part
        if (StringUtils.isNotBlank(getContent())) {
            tagsb.append(getIndent(level + 1)).append(getContent()).append(lineBreak);
        }

        // sub tag part
        for (HtmlWrapper tag : getSubTags()) {
            tagsb.append(tag.toString(level + 1));
        }

        // end tag part
        if (StringUtils.isNotBlank(getTag())) {
            tagsb.append(getIndent(level)).append(getEndTag()).append(lineBreak);
        }

        return tagsb.toString();
    }
}



下面是客户端调用 HtmlWrapper.java 的代码:

public class Client {
    public static void main(String[] args) {
        HtmlWrapper table = new HtmlWrapper.Builder().setTag("table").setAttrsInTag("border='1' style='border-collapse:collapse'").build();

        HtmlWrapper tbody = new HtmlWrapper.Builder().setTag("tbody").build();
        table.addSubTag(tbody);

        HtmlWrapper trh = new HtmlWrapper.Builder().setTag("tr").build();
        tbody.addSubTag(trh);

        HtmlWrapper thid = new HtmlWrapper.Builder().setTag("th").setContent("ID").build();
        HtmlWrapper thname = new HtmlWrapper.Builder().setTag("th").setContent("Name").build();
        trh.addSubTag(thid);
        trh.addSubTag(thname);

        HtmlWrapper trd = new HtmlWrapper.Builder().setTag("tr").build();
        tbody.addSubTag(trd);

        HtmlWrapper tdid = new HtmlWrapper.Builder().setTag("td").setContent("ID-0000001").build();
        HtmlWrapper tdname = new HtmlWrapper.Builder().setTag("td").setContent("Xiao Jia").build();
        trd.addSubTag(tdid);
        trd.addSubTag(tdname);

        System.out.println(table.toString());
    }
}



运行结果如下:

ID Name
ID-0000001 Xiao Jia


鸣谢

菜鸟教程

你可能感兴趣的:(Composite Pattern - 组合模式 - java 实现)