设计模式-5种创建型
2016-06-17 16:29
387 查看
设计模式系列博文:
1. 设计模式-6大设计原则
2. 设计模式-5种创建型
3. 设计模式-7种结构型
4. 设计模式-11种行为型
1. 饿汉式
2. 懒汉式
3. 双重锁定式
4. 枚举式
5. 静态内部类式
此处仅以最常见的双重锁定式为例!
适用于内存中只有唯一实例,避免频繁创建销毁。
注意:易导致内存泄露!不利于mock测试!
代码
输出:
使用时必须注意浅拷贝和深拷贝!
除了基本类型/String/包装类,其余的都是浅拷贝,只传递引用,没有传递对象,此时若要深拷贝,需要让其引用的对象也实现Cloneable接口并复写clone方法
关于Java-克隆
代码:
输出:
与set方法的区别是每次设置参数都返回builder自身,之后再根据builder构造对象
当建造过程很繁琐时,建议增加Director-导演类,封装建造过程
代码:
输出:
也可以不使用反射,而用枚举,那样的话,性能会好一点,但是却不能对修改关闭了,每添加一个新的产品类,都需要修改工厂类
代码:
输出:
将产品和工厂的依赖关系抽象化,不再依赖具体的实现类,方便拓展。
一个具体产品对应一个具体工厂。
代码:
输出:
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
代码:
输出:
一般喜欢将简单工厂模式归入工厂方法模式之中,但我觉得工厂方法模式其实和抽象工厂模式更像一点。
菜鸟一枚,水平有限,欢迎大家指出博文中的不足之处,小鱼将不胜感激!@qq:630709658
1. 设计模式-6大设计原则
2. 设计模式-5种创建型
3. 设计模式-7种结构型
4. 设计模式-11种行为型
1.单例模式
单例模式的实现,一共有5种方式:1. 饿汉式
2. 懒汉式
3. 双重锁定式
4. 枚举式
5. 静态内部类式
此处仅以最常见的双重锁定式为例!
适用于内存中只有唯一实例,避免频繁创建销毁。
注意:易导致内存泄露!不利于mock测试!
代码
package base.designpattern.creational; /** * 单例模式 * <p> * 案例:臣子觐见皇帝 * Created by yutianran on 16/7/1. */ public class SingletonPattern { public static void main(String[] args) { for (int i = 0; i < 10; i++) { //每次都有一个臣子觐见皇帝 Emperor emperor = Emperor.getInstance(); Minister minister = new Minister(); minister.see(emperor); } } //皇帝 public static class Emperor { private static Emperor instance; //禁止外部创建 private Emperor() { } //双重锁定式 public static Emperor getInstance() { if (null == instance) { synchronized (Emperor.class) { if (null == instance) { instance = new Emperor(); } } } return instance; } } //臣子 public static class Minister { public void see(Emperor emperor) { System.out.println("臣子:" + this + "\t觐见皇帝:" + emperor); } } }
输出:
2.原型模式
内存二进制流的拷贝,优于直接new对象使用时必须注意浅拷贝和深拷贝!
除了基本类型/String/包装类,其余的都是浅拷贝,只传递引用,没有传递对象,此时若要深拷贝,需要让其引用的对象也实现Cloneable接口并复写clone方法
关于Java-克隆
代码:
package base.designpattern.creational; /** * 原型模式 * <p> * 案例:盗版书 * Created by yutianran on 16/7/1. */ public class PrototypePattern { public static void main(String[] args) { //正版书 Book src = new Book("设计模式之禅"); src.setPreface(new Preface("这是一本介绍设计模式的书")); //盗版书 Book pirate = src.clone(); //修改书名 pirate.setName("设计模式之禅-Clone"); //修改序言 Preface preface = pirate.getPreface(); preface.setDesc("这是一本介绍设计模式的书-Clone"); System.out.println("正版书:" + src.toString()); System.out.println("盗版书:" + pirate.toString()); } //书 public static class Book implements Cloneable { private String name;//书名 private Preface preface;//序言 public Book(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Preface getPreface() { return preface; } public void setPreface(Preface preface) { this.preface = preface; } @Override protected Book clone() { Book clone = null; try { clone = (Book) super.clone(); //这里必须同时调用引用对象的clone方法 clone.preface = this.preface.clone(); } catch (CloneNotSupportedException e) { System.out.println("克隆出错:" + e.getMessage()); } return clone; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", preface=" + preface + '}'; } } //序言 public static class Preface implements Cloneable { private String desc;//介绍 public Preface(String desc) { this.desc = desc; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } @Override protected Preface clone() { Preface clone = null; try { clone = (Preface) super.clone(); } catch (CloneNotSupportedException e) { System.out.println("克隆出错:" + e.getMessage()); } return clone; } @Override public String toString() { return "Preface{" + "desc='" + desc + '\'' + '}'; } } }
输出:
3.建造者模式
链式创建,不必在构造方法中传入过多参数,或构造之后分开set与set方法的区别是每次设置参数都返回builder自身,之后再根据builder构造对象
当建造过程很繁琐时,建议增加Director-导演类,封装建造过程
代码:
package base.designpattern.creational; /** * 建造者模式 * <p> * 案例:创建网络请求 * Created by yutianran on 16/7/1. */ public class BuilderPattern { public static void main(String[] args) { String url = "http://baidu.com"; Request request = new Request.Builder() .url(url) .method("POST") .headers("Content-Type:application/json;charset=UTF-8") .body("{\"userId\":145}") .tag(url) .build(); System.out.println("网络请求:" + request.toString()); } //网络请求类 public static class Request { private String url; private String method; private String headers; private String body; private String tag; public Request(Builder builder) { if (null == builder.url) { throw new IllegalArgumentException("url == null"); } this.url = builder.url; this.method = builder.method; this.headers = builder.headers; this.body = builder.body; this.tag = builder.tag; } public String getUrl() { return url; } public String getMethod() { return method; } public String getHeaders() { return headers; } public String getBody() { return body; } public String getTag() { return tag; } @Override public String toString() { return "Request{" + "url='" + url + '\'' + ", methodB='" + method + '\'' + ", headers='" + headers + '\'' + ", body='" + body + '\'' + ", tag='" + tag + '\'' + '}'; } //建造者 public static class Builder { private String url; private String method; private String headers; private String body; private String tag; public Builder url(String url) { this.url = url; return this; } public Builder method(String method) { this.method = method; return this; } public Builder headers(String headers) { this.headers = headers; return this; } public Builder body(String body) { this.body = body; return this; } public Builder tag(String tag) { this.tag = tag; return this; } public Request build() { return new Request(this); } } } }
输出:
4.静态工厂模式
静态工厂类似于一个管理类,决定创建出哪一种产品类的实例。也可以不使用反射,而用枚举,那样的话,性能会好一点,但是却不能对修改关闭了,每添加一个新的产品类,都需要修改工厂类
代码:
package base.designpattern.creational; /** * 简单工厂模式 * <p> * Created by yutianran on 16/7/1. */ public class SimpleFactoryPattern { public static void main(String args[]) { IProduct product = SimpleFactory.produce(ProductA.class); product.method(); } //抽象产品 public static abstract class IProduct { public abstract void method(); } //具体产品A public static class ProductA extends IProduct { @Override public void method() { System.out.println("I'm ProductA!"); } } //具体产品B public static class ProductB extends IProduct { @Override public void method() { System.out.println("I'm ProductB!"); } } //静态工厂 public static class SimpleFactory { public static <T extends IProduct> T produce(Class<T> clazz) { IProduct human = null; try { human = (IProduct) Class.forName(clazz.getName()).newInstance(); } catch (Exception e) { System.out.println("创建错误:" + e.getMessage()); } return (T) human; } } }
输出:
5.工厂方法模式
不只是产品有抽象父类,工厂也有抽象父类!将产品和工厂的依赖关系抽象化,不再依赖具体的实现类,方便拓展。
一个具体产品对应一个具体工厂。
代码:
package base.designpattern.creational; /** * 工厂方法模式 * <p> * Created by yutianran on 16/7/1. */ public class FactoryMethodPattern { public static void main(String[] args) { AbstractFactory factoryA = new ConcreteFactoryA(); AbstractProduct product = factoryA.produce(); product.method(); } //抽象产品 public static abstract class AbstractProduct { public abstract void method(); } //抽象工厂 public static abstract class AbstractFactory { public abstract AbstractProduct produce(); } //具体产品 public static class ProductA extends AbstractProduct { @Override public void method() { System.out.println("I'm ProductA!"); } } public static class ProductB extends AbstractProduct { @Override public void method() { System.out.println("I'm ProductB!"); } } //具体工厂 public static class ConcreteFactoryA extends AbstractFactory { @Override public ProductA produce() { return new ProductA(); } } public static class ConcreteFactoryB extends AbstractFactory { @Override public ProductB produce() { return new ProductB(); } } }
输出:
6.抽象工厂模式
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
代码:
package base.designpattern.creational; /** * 抽象工厂模式 * <p> * Created by yutianran on 16/7/1. */ public class AbstractFactoryPattern { public static void main(String[] args) { AbstractFactory factory = new ConcreteFactory1(); AbstractProductA producta1 = factory.produceA(); AbstractProductB productb1 = factory.produceB(); producta1.methodA(); productb1.methodB(); } //抽象产品族 public static abstract class AbstractProductA { public abstract void methodA(); } public static abstract class AbstractProductB { public abstract void methodB(); } //抽象工厂 public static abstract class AbstractFactory { public abstract AbstractProductA produceA(); public abstract AbstractProductB produceB(); } //具体产品 public static class ProductA1 extends AbstractProductA { @Override public void methodA() { System.out.println("Im ProductA1!"); } } public static class ProductA2 extends AbstractProductA { @Override public void methodA() { System.out.println("Im ProductA2!"); } } public static class ProductB1 extends AbstractProductB { @Override public void methodB() { System.out.println("Im ProductB1!"); } } public static class ProductB2 extends AbstractProductB { @Override public void methodB() { System.out.println("Im ProductB2!"); } } //具体工厂 public static class ConcreteFactory1 extends AbstractFactory { @Override public AbstractProductA produceA() { return new ProductA1(); } @Override public AbstractProductB produceB() { return new ProductB1(); } } public static class ConcreteFactory2 extends AbstractFactory { @Override public AbstractProductA produceA() { return new ProductA2(); } @Override public AbstractProductB produceB() { return new ProductB2(); } } }
输出:
一般喜欢将简单工厂模式归入工厂方法模式之中,但我觉得工厂方法模式其实和抽象工厂模式更像一点。
菜鸟一枚,水平有限,欢迎大家指出博文中的不足之处,小鱼将不胜感激!@qq:630709658
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用
- 详解C#设计模式编程中生成器模式的使用