创建型模式
关注点--怎样创建对象
单例模式
原型模式
工厂方法模式
抽象工厂模式
建造者模式
一、单例模式(Singleton)
定义
一个类只有一个实例,且该类能自行创建这种实例。
特点
只有一个实例
能自行创建实例
对外提供一个能访问该实例的全局访问点
应用
饿汉式
public class SingletonDmeo{ // 创建一个该类私有的对象 private SingletonDmeo instance = new SingletonDemo(); // 构造器私有化,禁止其他类创建对象 private SingletonDmeo(){} // 创建一个的静态方法返回对象 pubic static SingletonDemo getInstance(){ return this.instance; } }
简单明了且在多线程环境下可以不会收到任何影响
在类加载的时候就会产生一个该类的对象
懒汉式
public class SingletonDemo{ // 创建一个私有实例,但是不初始化 private SingletonDemo instance; // 构造器私有化,禁止其他类创建对象 private SingletonDmeo(){} // 创建一个的静态方法返回对象 pubic static SingletonDemo getInstance(){ if(instance == null){ instance = new SingletonDemo(); } return instance; } }
这种方法类加载的时候不会创建对象,只是在需要的时候判断实例是否为空,如果为空则创建一个。但是在多线程环境中使用该方法时这种方式可能会创建出多个实例。
public class SingletonDemo{ private volatile SingletonDemo instance; private SingletonDemo(){} public static synchronized SingletonDemo getInstance(){ if(instance == null){ instance = new SingletonDemo(); } return instance; } }
通过synchronized锁定方法中的代码,解决多线程中可能或出现的创建多个实例的问题。但是由于其他线程需要等待锁,所以效率比较慢。
public class SingletoDemo{ private volatile SingletonDemo instance; private SingletonDemo(){} public static SingletonDemo getInstance(){ if(instance == null){ synchronized{ if(instance == null){ instance = new SingletonDemo(); } } } return instance; } }
Double Check提升效率,比较完美的方法。
内部类
public class SingletonDemo{ private SingletonDemo(){} private static class SingletonDemoHolder{ private final static SingletonDemo INSTANCE = new SingletonDemo() } public static SingletonDemo getInstance(){ return SingletonDemoHolder.INSTANCE; } }
枚举类(Effective Java推荐)
public enum SingletonDemo{ INSTANCE; }
二、原型模式(Prototype)
定义
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个与原型相同或者相似的对象
通过原型模式创建对象非常高效,无需知道创建对象的细节。
结构
抽象原型类
具体原型类
访问类
应用
public class MonkeySun implements Cloneable { public MonkeySun(){ System.out.println("创建了一个孙悟空实例"); } @Override protected Object clone() throws CloneNotSupportedException { System.out.print("复制了一个孙悟空实例"); return super.clone(); } }class Client { public static void main(String[] args) throws CloneNotSupportedException { MonkeySun monkeySun = new MonkeySun(); MonkeySun monkeySunCopy = (MonkeySun) monkeySun.clone(); System.out.println(monkeySun == monkeySunCopy); //false } }
上述例子中MonkeySun
为具体原型类,Java自带的Cloneable
接口抽象原型类
三、工厂方法模式(Factory Method)
定义
定义一个创建产品对象的接口,将产品对象的实际创捷工作推迟到具体的工厂类中。满足创建性模式的“创建与使用相分离”的特点。
优点以及缺点
优点
客户端只需要知道具体工厂的名称就可以得到所需的产品,无需知道具体产品创建的过程,
系统增加新的产品时无需对原有工厂进行修改,只需要添加新的产品类以及与之对应的工厂类,满足开闭原则。
缺点
每增加一个产品就需要增加一个具体的产品类以及其对应的工厂类,这增加了系统的复杂度。
结构
抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法createProduct()来创建产品
具体工厂(ConcreteFactory):主要实现抽象工厂中的抽象方法,完成产品的创建
抽象产品(Product):定义了产品的规范,描述了产品的主要特征和功能。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它与具体工厂一一对应。
应用
汽车生产
汽车工厂接口
public interface CarFactory{ public ICar createCar(); }
汽车接口
public interface ICar{ public void energy(); }
特斯拉工厂
public class TeslaFactory implements ICarFactory { @Override public ICar createCar() { return new TeslaCar(); } }
奔驰工厂
public class BenzFactory implements ICarFactory { @Override public ICar createCar() { return new BenzCar(); } }
特斯拉汽车
public class TeslaCar implements ICar { @Override public void energy() { System.out.println("特斯拉使用电......"); } }
奔驰汽车
public class BenzCar implements ICar { @Override public void energy() { System.out.println("奔驰汽车用汽油....."); } }
场景
客户只知道创建产品的工厂名,不知道具体的产品
创建对象的任务由多个具体工厂中的某一个完成,而抽象工厂只提供创建产品的接口
客户不关心创建产品的细节,只关心产品的品牌
四、抽象工厂模式(Abstract Factory)
定义
一种为访问类提供一个创建一组相关或者相互依赖的接口,且访问类不需要指定所需产品的具体类就可以得到同组不同等级的产品模式结构。
结构
抽象工厂(Abstract Factory):提供创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品。
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品
具体产品(Concrete Product):实现了抽象产品角色所定义的接口,由具体工厂创建,它同具体工厂之间是多对一关系。
应用场景
需要创建的产品是一系列相互关联,相互依赖的产品组时。
系统中有多个产品组,但是每次只使用其中一族产品。
系统提供了产品的类库,且所有产品的接口相同。客户端不依赖产品实例的创建细节和内部结构。
五、建造者模式
定义
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。
将一个复杂的对象分为多个简单的对象,然后一步步构建而成。将变与不变分离,即产品的组成部分使不变的,但每一部分使可以灵活选择的。
优点与缺点
优点:
各个部分的建造者相互独立,有利于系统的扩展。
客户端不必知道产品内部组成细节,便于控制细节风险。
缺点:
产品的组成部分必须相同,限制了产品的使用部分。
如果产品内部变化复杂,该模式会增加很多的建造者类。
结构
产品角色(Product):它是多个组成部件的复杂对象,由具体建造者来创建其各个部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法getResult()。
具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
0条评论
点击登录参与评论