您的位置:首页 > 其它

设计模式-5种创建型

2016-06-17 16:29 387 查看
设计模式系列博文:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式