《设计模式》12.组合模式(结构型)

又称“整体—部分”模式,组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构,使用户对单个对象和组合对象具有访问一致性。

角色

抽象构件(Component):抽象类,定义叶子构件和树枝构件的公共接口,可提供默认实现,叶子构件中提供空实现或抛出异常
叶子构件(Leaf):没有子节点,实现抽象构件中的公共接口(空实现或抛出异常)
树枝构件(Composite):包含子节点,子节点可以是叶子构件也可以是树枝构件,实现抽象构件中公共接口

抽象构件 Component

public abstract class Component {
    protected static final String SPACE = " ";
    protected static final String hyphen = "-";
    private String name;
    public Component(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public abstract boolean add(Component component);
    public abstract Component getChild(int index);
    public abstract boolean remove(Component c);
    public abstract void operation(int spaces);
}

叶子构件 Leaf

import java.util.Collections;

public class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    public boolean add(Component component) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public Component getChild(int index) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(Component c) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public void operation(int spaces) {
        StringBuffer line = new StringBuffer();
        if (spaces > 0) {
            line.append(String.join("", Collections.nCopies(spaces, SPACE)));
            line.append("|- ");
        }
        line.append(getName());
        System.out.println(line);
    }
}

树枝构件 Composite

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Composite extends Component {
    private List<Component> components = new ArrayList<Component>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public boolean add(Component component) {
        return components.add(component);
    }

    @Override
    public Component getChild(int index) {
        return components.get(index);
    }

    @Override
    public boolean remove(Component c) {
        return components.remove(c);
    }

    @Override
    public void operation(int spaces) {
        StringBuffer line = new StringBuffer();
        if (spaces > 0) {
            line.append(String.join("", Collections.nCopies(spaces, SPACE)));
            line.append("|- ");
        }
        line.append(getName());
        System.out.println(line);

        int length = line.length() - spaces;
        for (Component component : components) {
            int mid = (length % 2 == 0) ? (length / 2 - 1) : (length / 2 + 1);
            component.operation(mid + spaces);
        }
    }
}

测试类

public class CompositeTester {
    public static void main(String args[]) {
        Component root = new Composite("root");
        root.add(new Leaf("node#1"));
        Component branch2 = new Composite("branch#2");
        root.add(branch2);
        root.add(new Leaf("node#2"));

        branch2.add(new Leaf("node#3"));
        branch2.add(new Leaf("node#4"));
        Composite branch3 = new Composite("branch#3");
        branch2.add(branch3);

        branch3.add(new Leaf("node#5"));
        branch3.add(new Leaf("node#6"));
        branch3.add(new Leaf("node#7"));

        root.operation(0);

        Component leaf = new Leaf("node#8");
        leaf.add(new Leaf("node#9"));
    }
}

输出

root
 |- node#1
 |- branch#2
       |- node#3
       |- node#4
       |- branch#3
             |- node#5
             |- node#6
             |- node#7
 |- node#2
Exception in thread "main" java.lang.UnsupportedOperationException: Leaf
	at com.designpatterns.composite.base.Leaf.add(Leaf.java:12)
	at com.designpatterns.composite.base.CompositeTester.main(CompositeTester.java:23)

举例:文件 & 文件夹

抽象构件 File

import lombok.Getter;
import lombok.Setter;

import java.util.List;

public abstract class File {
    @Getter @Setter
    private String pathname;
    @Getter @Setter
    private String path;
    @Getter @Setter
    private String fileName;
    public File(String pathname) {
        if (pathname == null) {
            throw new IllegalArgumentException(pathname);
        }
        pathname = pathname.replace("/", java.io.File.separator);
        if (!pathname.contains(java.io.File.separator)) {
            throw new IllegalArgumentException(pathname);
        }
        this.pathname = pathname;
        int indexOfSep = pathname.lastIndexOf(java.io.File.separator);
        this.path = pathname.substring(0, indexOfSep);
        this.fileName = pathname.substring(indexOfSep + 1);
    }

    public File(File parent, String fileName) {
        if (parent == null) {
            throw new IllegalArgumentException("null");
        }
        if (fileName == null || fileName.isEmpty()) {
            throw new IllegalArgumentException(fileName);
        }

        this.path = parent.getPathname();
        this.fileName = fileName;
        this.pathname = parent.getPathname() + java.io.File.separator + fileName;
    }

    public static boolean isDirectory(String fileName) {
        return !fileName.contains(".");
    }

    public abstract boolean add(File f);
    public abstract File getChild(String fileName);
    public abstract boolean remove(String fileName);
    public abstract List<String> list();
}

叶子构件 Text

import java.util.List;

public class Text extends File {
    public Text(String pathname) {
        super(pathname);
    }

    public Text(File parent, String fileName) {
        super(parent, fileName);
    }

    @Override
    public boolean add(File f) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public File getChild(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public List<String> list() {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }
}

叶子构件 Audio

import java.util.List;

public class Audio extends File {
    public Audio(String pathname) {
        super(pathname);
    }

    public Audio(File parent, String fileName) {
        super(parent, fileName);
    }

    @Override
    public boolean add(File f) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public File getChild(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public List<String> list() {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }
}

叶子构件 Video

import java.util.List;

public class Video extends File {
    public Video(String pathname) {
        super(pathname);
    }

    public Video(File parent, String fileName) {
        super(parent, fileName);
    }

    @Override
    public boolean add(File f) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public File getChild(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(String fileName) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public List<String> list() {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }
}

树枝构件 Directory

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Directory extends File {
    private List<File> files = new ArrayList<>();
    public Directory(String pathname) {
        super(pathname);
    }

    public Directory(File parent, String fileName) {
        super(parent, fileName);
    }

    @Override
    public boolean add(File f) {
        return files.add(f);
    }

    @Override
    public File getChild(String fileName) {
        Iterator<File> iter = files.iterator();
        while (iter.hasNext()) {
            File f = iter.next();
            if (f.getFileName().equals(fileName)) {
                return f;
            }
        }
        return null;
    }

    @Override
    public boolean remove(String fileName) {
        Iterator<File> iter = files.iterator();
        while (iter.hasNext()) {
            File f = iter.next();
            if (f.getFileName().equals(fileName)) {
                iter.remove();
                return true;
            }
        }
        return false;
    }

    @Override
    public List<String> list() {
        List<String> pathnames = new ArrayList<>();
        for (File f : files) {
            pathnames.add(f.getPathname());
            if (isDirectory(f.getFileName())) {
                pathnames.addAll(f.list());
            }
        }
        return pathnames;
    }
}

测试类

import java.util.List;

public class FileTester {
    public static void main(String args[]) {
        File root = new Directory("D:/root");
        File readme = new Text(root, "readme.txt");
        root.add(readme);

        File musicListTxt = new Text(root, "music-list.txt");
        root.add(musicListTxt);

        File musicDir = new Directory(root, "musics");
        File giveMeYourHeart = new Audio(musicDir, "give you my heart.mp3");
        File heyJude = new Audio(musicDir, "hey judy.wma");
        musicDir.add(giveMeYourHeart);
        musicDir.add(heyJude);
        root.add(musicDir);

        File videoListTxt = new Text(root, "video-list.txt");
        root.add(videoListTxt);

        File videoDir = new Directory(root, "videos");
        File superMan = new Video(videoDir, "超人.rmvb");
        videoDir.add(superMan);
        root.add(videoDir);

        List<String> pathnames = root.list();
        for (String pathname : pathnames) {
            System.out.println(pathname);
        }

        File file = root.getChild("readme.txt");
        System.out.println(file.getPathname());
    }
}
D:\root\readme.txt
D:\root\music-list.txt
D:\root\musics
D:\root\musics\give you my heart.mp3
D:\root\musics\hey judy.wma
D:\root\video-list.txt
D:\root\videos
D:\root\videos\超人.rmvb
D:\root\readme.txt

举例2:html元素

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.util.HashMap;
import java.util.Map;

public abstract class Element {
    @Getter
    private String tagName;

    protected long height;
    protected long lineHeight;
    protected long width;


    protected Margin margin = new Margin();
    private Border border = new Border();
    protected Padding padding = new Padding();
    protected Map<String, Object> styleCache = new HashMap<>();

    @Getter @Setter
    private String id;
    public Element(String tagName) {
        this.tagName = tagName;
    }

    public Element(String tagName, String id) {
        this.tagName = tagName;
        this.id = id;
    }


    public abstract boolean add(Element e);
    public abstract Element getChild(String id);
    public abstract boolean remove(Element e);
    public abstract boolean empty();
    public abstract void print(int tabs);


    public void addStyle(String name, Object value) {
        this.styleCache.put(name, value);
    }

    public void removeStyle(String name) {
        this.styleCache.remove(name);
    }

    public void setBorderTop(long top) {
        this.border.setTop(top);

        this.styleCache.put("border-top", top);
    }

    public void setBorderRight(long right) {
        this.border.setRight(right);
        this.styleCache.put("border-right", right);
    }

    public void setBorderBottom(long bottom) {
        this.border.setBottom(bottom);
        this.styleCache.put("border-bottom", bottom);
    }

    public void setBorderLeft(long left) {
        this.border.setLeft(left);
        this.styleCache.put("border-left", left);
    }

    public void setBorder(long topAndBottom, long leftAndRight) {
        this.border.setTop(topAndBottom);
        this.border.setRight(leftAndRight);
        this.border.setBottom(topAndBottom);
        this.border.setLeft(leftAndRight);

        this.styleCache.put("border-top", topAndBottom);
        this.styleCache.put("border-right", leftAndRight);
        this.styleCache.put("border-bottom", topAndBottom);
        this.styleCache.put("border-left", leftAndRight);
    }

    public void setBorder(long top, long right, long bottom, long left) {
        this.border.setTop(top);
        this.border.setRight(right);
        this.border.setBottom(bottom);
        this.border.setLeft(left);

        this.styleCache.put("border-top", top);
        this.styleCache.put("border-right", right);
        this.styleCache.put("border-bottom", bottom);
        this.styleCache.put("border-left", left);
    }

    public void setMarginTop(long top) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setMarginRight(long right) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setMarginBottom(long bottom) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setMarginLeft(long left) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setMargin(long topAndBottom, long leftAndRight) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setMargin(long top, long right, long bottom, long left) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPaddingTop(long top) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPaddingRight(long right) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPaddingBottom(long bottom) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPaddingLeft(long left) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPadding(long topAndBottom, long leftAndRight) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    public void setPadding(long top, long right, long bottom, long left) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Data
    public class Margin {
        private long top;
        private long left;
        private long right;
        private long bottom;
    }

    @Data
    public class Border {
        private long top;
        private long left;
        private long right;
        private long bottom;
    }

    @Data
    public class Padding {
        private long top;
        private long left;
        private long right;
        private long bottom;
    }
}
import java.util.Collections;
import java.util.Map;

public class InlineElement extends Element {
    private String text;
    public InlineElement(String tagName) {
        super(tagName);
        addStyle("display", "inline");
    }

    public InlineElement(String tagName, String id) {
        super(tagName, id);
        addStyle("display", "inline");
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public boolean add(Element e) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public Element getChild(String id) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(Element e) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean empty() {
        text = "";
        return true;
    }

    @Override
    public void print(int tabs) {
        String prefix = String.join("", Collections.nCopies(tabs, "\t"));
        StringBuffer styles = new StringBuffer();
        for (Map.Entry<String, Object> style : styleCache.entrySet()) {
            if (styles.length() > 0) {
                styles.append(";");
            }
            styles.append(style.getKey()).append(":").append(style.getValue());
        }
        StringBuffer content = new StringBuffer();
        content.append(prefix).append("<").append(getTagName());
        if (getId() != null && !getId().isEmpty()) {
            content.append(" id=\"").append(getId());
        }
        content.append("\" style=\"").append(styles).append("\">");
        if (text != null && !text.isEmpty()) {
            content.append(text);
        }
        content.append("</").append(getTagName()).append(">");
        System.out.println(content);
    }
}
import java.util.Collections;
import java.util.Map;

public class InlineBlockElement extends Element {
    private String text;
    public InlineBlockElement(String tagName) {
        super(tagName);
        addStyle("display", "inline-block");
        addStyle("float", "left");// or right
        addStyle("position", "absolute");// or fixed
    }

    public InlineBlockElement(String tagName, String id) {
        super(tagName, id);
        addStyle("display", "inline-block");
        addStyle("float", "left");// or right
        addStyle("position", "absolute");// or fixed
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    @Override
    public boolean add(Element e) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public Element getChild(String id) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean remove(Element e) {
        throw new UnsupportedOperationException(getClass().getSimpleName());
    }

    @Override
    public boolean empty() {
        text = "";
        return true;
    }

    @Override
    public void print(int tabs) {
        String prefix = String.join("", Collections.nCopies(tabs, "\t"));
        StringBuffer styles = new StringBuffer();
        for (Map.Entry<String, Object> style : styleCache.entrySet()) {
            if (styles.length() > 0) {
                styles.append(";");
            }
            styles.append(style.getKey()).append(":").append(style.getValue());
        }
        StringBuffer content = new StringBuffer();
        content.append(prefix).append("<").append(getTagName());
        if (getId() != null && !getId().isEmpty()) {
            content.append(" id=\"").append(getId());
        }
        content.append("\" style=\"").append(styles).append("\">");
        if (text != null && !text.isEmpty()) {
            content.append(text);
        }
        content.append(prefix).append("</").append(getTagName()).append(">");
        System.out.println(content);
    }

    public void setMarginTop(long top) {
        this.margin.setTop(top);
        this.styleCache.put("margin-top", top);
    }

    public void setMarginRight(long right) {
        this.margin.setRight(right);
        this.styleCache.put("margin-right", right);
    }

    public void setMarginBottom(long bottom) {
        this.margin.setBottom(bottom);
        this.styleCache.put("margin-bottom", bottom);
    }

    public void setMarginLeft(long left) {
        this.margin.setLeft(left);

        this.styleCache.put("margin-left", left);
    }

    public void setMargin(long topAndBottom, long leftAndRight) {
        this.margin.setTop(topAndBottom);
        this.margin.setRight(leftAndRight);
        this.margin.setBottom(topAndBottom);
        this.margin.setLeft(leftAndRight);

        this.styleCache.put("margin-top", topAndBottom);
        this.styleCache.put("margin-right", leftAndRight);
        this.styleCache.put("margin-bottom", topAndBottom);
        this.styleCache.put("margin-left", leftAndRight);
    }

    public void setMargin(long top, long right, long bottom, long left) {
        this.margin.setTop(top);
        this.margin.setRight(right);
        this.margin.setBottom(bottom);
        this.margin.setLeft(left);

        this.styleCache.put("margin-top", top);
        this.styleCache.put("margin-right", right);
        this.styleCache.put("margin-bottom", bottom);
        this.styleCache.put("margin-left", right);
    }

    public void setPaddingTop(long top) {
        this.padding.setTop(top);
        this.styleCache.put("padding-top", top);
    }

    public void setPaddingRight(long right) {
        this.padding.setRight(right);
        this.styleCache.put("padding-right", right);
    }

    public void setPaddingBottom(long bottom) {
        this.padding.setBottom(bottom);
        this.styleCache.put("padding-bottom", bottom);
    }

    public void setPaddingLeft(long left) {
        this.padding.setLeft(left);
        this.styleCache.put("padding-left", left);
    }

    public void setPadding(long topAndBottom, long leftAndRight) {
        this.padding.setTop(topAndBottom);
        this.padding.setRight(leftAndRight);
        this.padding.setBottom(topAndBottom);
        this.padding.setLeft(leftAndRight);

        this.styleCache.put("padding-top", topAndBottom);
        this.styleCache.put("padding-right", leftAndRight);
        this.styleCache.put("padding-bottom", topAndBottom);
        this.styleCache.put("padding-left", leftAndRight);
    }

    public void setPadding(long top, long right, long bottom, long left) {
        this.padding.setTop(top);
        this.padding.setRight(right);
        this.padding.setBottom(bottom);
        this.padding.setLeft(left);

        this.styleCache.put("padding-top", top);
        this.styleCache.put("padding-right", right);
        this.styleCache.put("padding-bottom", bottom);
        this.styleCache.put("padding-left", left);
    }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class BlockElement extends Element {
    private String text;
    private Element parent;
    private List<Element> children = new ArrayList<>();

    public BlockElement(String tagName) {
        super(tagName);
        addStyle("display", "block");
    }

    public BlockElement(String tagName, String id) {
        super(tagName, id);
        addStyle("display", "block");
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public long getHeight() {
        return this.height;
    }

    public void setHeight(long height) {
        this.height = height;
        this.styleCache.put("height", height);
    }

    public long getLineHeight() {
        return this.lineHeight;
    }

    public void setLineHeight(long lineHeight) {
        this.lineHeight = lineHeight;
        this.styleCache.put("line-height", lineHeight);
    }

    public long getWidth() {
        return this.width;
    }

    public void setWidth(long width) {
        this.width = width;
        this.styleCache.put("width", width);
    }

    @Override
    public boolean add(Element e) {
        return children.add(e);
    }

    @Override
    public Element getChild(String id) {
        for (Element child : children) {
            if (child.getId().equals(id)) {
                return child;
            }
        }
        return null;
    }

    @Override
    public boolean remove(Element e) {
        return children.remove(e);
    }

    @Override
    public boolean empty() {
        children.clear();
        return true;
    }

    @Override
    public void print(int tabs) {
        StringBuffer styles = new StringBuffer();
        for (Map.Entry<String, Object> style : styleCache.entrySet()) {
            if (styles.length() > 0) {
                styles.append(";");
            }
            styles.append(style.getKey()).append(":").append(style.getValue());
        }
        String prefix = String.join("", Collections.nCopies(tabs, "\t"));
        StringBuffer startTag = new StringBuffer();
        startTag.append(prefix).append("<").append(getTagName());
        if (getId() != null && !getId().isEmpty()) {
            startTag.append(" id=\"").append(getId());
        }
        startTag.append("\" style=\"").append(styles).append("\">" );
        System.out.println(startTag);
        for (Element child : children) {
            child.print(tabs + 1);
        }
        System.out.println(prefix + "</" + getTagName() + ">");
    }

    public void setMarginTop(long top) {
        this.margin.setTop(top);
        this.styleCache.put("margin-top", top);
    }

    public void setMarginRight(long right) {
        this.margin.setRight(right);
        this.styleCache.put("margin-right", right);
    }

    public void setMarginBottom(long bottom) {
        this.margin.setBottom(bottom);
        this.styleCache.put("margin-bottom", bottom);
    }

    public void setMarginLeft(long left) {
        this.margin.setLeft(left);

        this.styleCache.put("margin-left", left);
    }

    public void setMargin(long topAndBottom, long leftAndRight) {
        this.margin.setTop(topAndBottom);
        this.margin.setRight(leftAndRight);
        this.margin.setBottom(topAndBottom);
        this.margin.setLeft(leftAndRight);

        this.styleCache.put("margin-top", topAndBottom);
        this.styleCache.put("margin-right", leftAndRight);
        this.styleCache.put("margin-bottom", topAndBottom);
        this.styleCache.put("margin-left", leftAndRight);
    }

    public void setMargin(long top, long right, long bottom, long left) {
        this.margin.setTop(top);
        this.margin.setRight(right);
        this.margin.setBottom(bottom);
        this.margin.setLeft(left);

        this.styleCache.put("margin-top", top);
        this.styleCache.put("margin-right", right);
        this.styleCache.put("margin-bottom", bottom);
        this.styleCache.put("margin-left", right);
    }

    public void setPaddingTop(long top) {
        this.padding.setTop(top);
        this.styleCache.put("padding-top", top);
    }

    public void setPaddingRight(long right) {
        this.padding.setRight(right);
        this.styleCache.put("padding-right", right);
    }

    public void setPaddingBottom(long bottom) {
        this.padding.setBottom(bottom);
        this.styleCache.put("padding-bottom", bottom);
    }

    public void setPaddingLeft(long left) {
        this.padding.setLeft(left);
        this.styleCache.put("padding-left", left);
    }

    public void setPadding(long topAndBottom, long leftAndRight) {
        this.padding.setTop(topAndBottom);
        this.padding.setRight(leftAndRight);
        this.padding.setBottom(topAndBottom);
        this.padding.setLeft(leftAndRight);

        this.styleCache.put("padding-top", topAndBottom);
        this.styleCache.put("padding-right", leftAndRight);
        this.styleCache.put("padding-bottom", topAndBottom);
        this.styleCache.put("padding-left", leftAndRight);
    }

    public void setPadding(long top, long right, long bottom, long left) {
        this.padding.setTop(top);
        this.padding.setRight(right);
        this.padding.setBottom(bottom);
        this.padding.setLeft(left);

        this.styleCache.put("padding-top", top);
        this.styleCache.put("padding-right", right);
        this.styleCache.put("padding-bottom", bottom);
        this.styleCache.put("padding-left", left);
    }
}
public class ElementTester {
    public static void main(String args[]) {
        Element div = new BlockElement("div", "content");
        InlineElement span = new InlineElement("span", "title");
        span.setText("设计模式之组合模式");
        Element a = new InlineElement("a", "goBaidu");
        Element input = new InlineBlockElement("input", "clickMe");
        Element content = new BlockElement("div", "description");
        Element ul = new BlockElement("ul", "ul");
        BlockElement li1 = new BlockElement("li", "li-1");
        li1.setText("1. 通过 a 标签跳到百度首页");
        BlockElement li2 = new BlockElement("li", "li-2");
        li1.setText("2. 这是一个点击按钮");

        ul.add(li1);
        ul.add(li2);
        content.add(ul);

        div.add(span);
        div.add(a);
        div.add(input);
        div.add(content);

        div.print(0);
    }
}
<div id="content" style="display:block">
	<span id="title" style="display:inline">设计模式之组合模式</span>
	<a id="goBaidu" style="display:inline"></a>
	<input id="clickMe" style="display:inline-block;position:absolute;float:left">	</input>
	<div id="description" style="display:block">
		<ul id="ul" style="display:block">
			<li id="li-1" style="display:block">
			</li>
			<li id="li-2" style="display:block">
			</li>
		</ul>
	</div>
</div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值