单例模式
这个太简单了,贴一下代码吧
public class Singleton {
private static Singleton singleton = new Singleton();
public static Singleton getInstance() {
return singleton;
}
// 私有构造函数,禁止显示构造
private Singleton() {
System.out.println("创建一个单例实例");
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
Singleton another = Singleton.getInstance();
System.out.println(another.toString());
System.out.println(singleton.toString());
}
}
Prototype模式(不常用)
- 生成某个类的对象非常麻烦,我们希望通过复制已有的对象,而非重新生成
- 本质上还是调用了clone方法,只是做了一层包装而已
示例
public class Manager {
private HashMap showcase = new HashMap();
public void register(String name, Product proto) {
showcase.put(name, proto);
}
public Product create(String protoName) {
Product p = (Product) showcase.get(protoName);
return p.createClone();
}
}
public interface Product extends Cloneable {
void use(String s);
Product createClone();
}
public class MessageBox implements Product {
private char decoChar;
public MessageBox(char decoChar) {
this.decoChar = decoChar;
}
@Override
public void use(String s) {
int length = s.getBytes().length;
for (int i = 0; i < length + 4; i++) {
System.out.print(decoChar);
}
System.out.println();
System.out.println(decoChar + " " + s + " " + decoChar);
for (int i = 0;i < length + 4; i++) {
System.out.print(decoChar);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
public class UnderlinePen implements Product {
private char ulChar;
public UnderlinePen(char ch) {
ulChar = ch;
}
@Override
public void use(String s) {
System.out.println(s);
for (int i = 0; i < s.length(); i++) {
System.out.print(ulChar);
}
System.out.println();
}
@Override
public Product createClone() {
Product p = null;
try {
p = (Product) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return p;
}
}
public class PrototypeTest {
public static void main(String[] args) {
Manager manager = new Manager();
UnderlinePen uPen = new UnderlinePen('~');
MessageBox mBox = new MessageBox('*');
MessageBox sBox = new MessageBox('/');
manager.register("warning box", mBox);
manager.register("slash box", sBox);
manager.register("strong message", uPen);
Product p1 = manager.create("strong message");
p1.use("hello world");
Product p2 = manager.create("slash box");
p2.use("hello world");
Product p3 = manager.create("warning box");
p3.use("hello world");
}
}
相关设计模式
- 命令模式
- 组合模式
- 装饰器模式
建造者模式
构造一个的时候需要先构造这个物体的各个部分,然后分阶段组装起来
示例
用建造者模式写一段编写文档的程序
- 标题
- 几个字符串
- 几条项目
public abstract class Builder {
public abstract void makeTitle(String title);
public abstract void makeString(String str);
public abstract void makeItems(String[] items);
public abstract void close();
}
public class Director {
private Builder builder;
public Director(Builder builder) { // 实际会用Builder的子类来实例化Director
this.builder = builder;
}
public void construct() {
builder.makeTitle("Greeting");
builder.makeString("从早上到下午");
builder.makeItems(new String[]{
"早上好",
"下午好"
});
builder.makeString("晚上");
builder.makeItems(new String[]{
"晚上好",
"晚安",
"再见"
});
builder.close();
}
}
public class HTMLBuilder extends Builder {
private String fileName;
private PrintWriter writer;
@Override
public void makeTitle(String title) {
try {
writer = new PrintWriter(new FileWriter(fileName));
} catch (IOException e) {
e.printStackTrace();
}
writer.println("<html><head><title>" + title + "</title></head><body>");
}
@Override
public void makeString(String str) {
writer.println("<h1>" + str + "</p>");
}
@Override
public void makeItems(String[] items) {
writer.println("<ul>");
for (String item: items) {
writer.println("<li>" + item + "</li>");
}
writer.println("</ul>");
}
@Override
public void close() {
writer.println("</body></html>");
writer.close();
}
public String getResult() {
return fileName;
}
}
public class TextBuilder extends Builder{
private StringBuffer buffer = new StringBuffer();
@Override
public void makeTitle(String title) {
buffer.append("==========================\n");
buffer.append("|" + title + "|\n");
buffer.append("\n");
}
@Override
public void makeString(String str) {
buffer.append("- " + str + "\n");
buffer.append("\n");
}
@Override
public void makeItems(String[] items) {
for (String item : items) {
buffer.append(" ." + item + "\n");
}
buffer.append("\n");
}
@Override
public void close() {
buffer.append("=========================\n");
}
public String getResult() {
return buffer.toString();
}
}
public class BuilderTest {
public static void main(String[] args) {
if (args.length != 1) {
usage();
System.exit(0);
}
if (args[0].equals("plain")) {
TextBuilder textBuilder = new TextBuilder();
Director director = new Director(textBuilder);
director.construct();
String result = textBuilder.getResult();
System.out.println(result);
} else if (args[0].equals("html")) {
HTMLBuilder htmlBuilder = new HTMLBuilder();
Director director = new Director(htmlBuilder);
director.construct();
String fileName = htmlBuilder.getResult();
System.out.println(fileName + " 文件编写完成");
} else {
usage();
System.exit(0);;
}
}
public static void usage() {
System.out.println("Usage: Java Main plain 编写纯文本文档");
System.out.println("Usage: Java Main html 编写HTML文档");
}
}
注意
- 谁知道什么:用户只知道Director,Director只知道Builder,但不知道具体的Builder。
- 在模板方法中,是基类指定了模板函数的调用顺序。但是在建造者模式中,是用户(Director)来调用Builer中的方法
相关设计模式
- 模板方法模式
- 组合模式
- 抽象工厂模式
抽象工厂模式
关联零件组成产品。代码太长了,这里就简单说一下自己的理解
- 有很多个类似的产品,在创建这些产品的时候,可以设置一个工厂类,用这个工厂类去new产品。
- 现在,产品变得更多了。这些产品被分成了若干品种,每个品种又有很多类似产品。这样就会多出一堆工厂类。
- 这时候就可以把这些工厂类抽象成一个抽象工厂,而生产产品的工厂类就去继承这个抽象工厂类。