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

角色

抽象构件(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);}@Overridepublic boolean add(Component component) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic Component getChild(int index) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(Component c) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic 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);}@Overridepublic boolean add(Component component) {return components.add(component);}@Overridepublic Component getChild(int index) {return components.get(index);}@Overridepublic boolean remove(Component c) {return components.remove(c);}@Overridepublic 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: Leafat 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 @Setterprivate String pathname;@Getter @Setterprivate String path;@Getter @Setterprivate 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);}@Overridepublic boolean add(File f) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic File getChild(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic 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);}@Overridepublic boolean add(File f) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic File getChild(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic 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);}@Overridepublic boolean add(File f) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic File getChild(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(String fileName) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic 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);}@Overridepublic boolean add(File f) {return files.add(f);}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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 {@Getterprivate 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 @Setterprivate 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());}@Datapublic class Margin {private long top;private long left;private long right;private long bottom;}@Datapublic class Border {private long top;private long left;private long right;private long bottom;}@Datapublic 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;}@Overridepublic boolean add(Element e) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic Element getChild(String id) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(Element e) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean empty() {text = "";return true;}@Overridepublic 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 rightaddStyle("position", "absolute");// or fixed}public InlineBlockElement(String tagName, String id) {super(tagName, id);addStyle("display", "inline-block");addStyle("float", "left");// or rightaddStyle("position", "absolute");// or fixed}public String getText() {return text;}public void setText(String text) {this.text = text;}@Overridepublic boolean add(Element e) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic Element getChild(String id) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean remove(Element e) {throw new UnsupportedOperationException(getClass().getSimpleName());}@Overridepublic boolean empty() {text = "";return true;}@Overridepublic 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);}@Overridepublic boolean add(Element e) {return children.add(e);}@Overridepublic Element getChild(String id) {for (Element child : children) {if (child.getId().equals(id)) {return child;}}return null;}@Overridepublic boolean remove(Element e) {return children.remove(e);}@Overridepublic boolean empty() {children.clear();return true;}@Overridepublic 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>

《设计模式》12.组合模式(结构型)相关推荐

  1. 设计模式深入学习---Component组合模式(结构型模式)

    Component组合模式是一个非常好用而且经常可以在大型项目中看到的设计模式.    首先我们来简单过一下什么是Component组合模式以及用该模式的情况和好处.Component组合模式就是将对 ...

  2. GOF设计模式之外观模式(结构型代理模式)

  3. GOF设计模式之代理模式(结构型代理模式)

  4. 结构型设计模式之组合模式

    结构型设计模式之组合模式 组合模式 应用场景 优缺点 主要角色 组合模式结构 分类 透明组合模式 创建抽象根节点 创建树枝节点 创建叶子节点 客户端调用 安全组合模式 创建抽象根节点 创建树枝节点 创 ...

  5. 设计模式(2)结构型模式

    结构型模式 结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效. 结构型模式: 适配器模式:用来把一个接口转化成另一个接口.使得原本由于接口不兼容而不能一起工作的那些类可以在一 ...

  6. 【设计模式】设计模式总结 ( 七大设计原则 | 创建型模式 | 结构型模式 | 行为型模式 ) ★★★

    文章目录 一.七大设计原则 1.开闭原则 2.依赖倒置原则 3.单一职责原则 4.接口隔离原则 5.迪米特原则 6.里氏替换原则 7.合成复用原则 二.创建型模式 0.简单工厂模式 ( 不属于 GOF ...

  7. 设计模式(三)结构型模式介绍及实例

    文章目录 一.适配器模式 1.1 适配器模式定义 1.2 适配器模式主要角色 1.3 适配器模式特点 1.4 适配器模式实现方式 1.4.1 类适配器模式 1.4.2 对象适配器模式 1.5 适配器模 ...

  8. 设计模式之组合模式(Composite)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  9. 1、【设计模式】组合模式

    java设计模式之组合模式 [学习难度:★★★☆☆,使用频率:★★★★☆]  树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式 ...

最新文章

  1. 第九期直播|《深度相机与应用》精彩回顾
  2. 2018.1.15 6周1次课
  3. Tomcat服务器server.xml详解
  4. 利用 Azure Functions 实现无服务器体系结构
  5. python是开源工具吗_微软最强 Python 自动化工具开源了!不用写一行代码
  6. kibana客户端工具操作ElasticSearch(增删改查三)
  7. Linux(CentOS 6.5)下配置Mono和Jexus并且部署ASP.NET MVC5
  8. 车辆出厂信息接口_航测遥感中心“漳州核电智慧工地管理系统平台”通过出厂验收...
  9. ORA-01012: not logged on 解决办法
  10. 八段数码管数字显示实验c语言,八段数码管显示实验.doc
  11. 2021(上海)第34届国际创业投资连锁加盟展览会
  12. 用python制作音乐_Python3使用PySynth制作音乐的方法
  13. 从零开始制作STM32F103RCT6小车(一)
  14. 危化品从业人员考试题目及答案
  15. Fractal Streets(经典分形递归+坐标旋转)
  16. Ubuntu20.04安装yum
  17. c语言 原子 字符串,Atomic operations library(原子操作库)
  18. UDP多播:一对多数据收发
  19. 关于VB中的 comct132.ocx问题!
  20. loop和goto用法

热门文章

  1. 思岚科技即将亮相2019上交会 展示机器人自主行走背后的技术
  2. Node.js 被分叉出一个项目 — Ayo.js,肿么了
  3. JAVA MemCache 史无前例的详细讲解!看完包精通MEMCACHE!
  4. 易诚互动在创业板更新招股书:上半年出现亏损,极其依赖阿里云
  5. Java SE 6 新特性: 对脚本语言的支持 [VERY GOOD]
  6. 学会用python识别图像
  7. mysql中哪种方式可以开启一个事务_网易技术类笔试题-2016
  8. 写在Doris毕业后的第一天
  9. 玩转Python的黑魔法手册
  10. C/C++黑魔法-字符串分割