设计模式学习——创建型模式(单例工厂建造者)
Posted <天各一方>
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式学习——创建型模式(单例工厂建造者)相关的知识,希望对你有一定的参考价值。
文章目录
单例模式
单例模式:保证一个类仅有一个实例,并且这个类提供一个全局的访问接口,某些对象在全局只需要一个,就可以使用单例模式。
单例模式的创建可以分为两种模式:提前加载和延迟加载。
提前加载模式:
public class Singleton
private static Singleton instance = new Singleton();
private Singleton()
public static Singleton getInstance()
return instance;
也叫饿汉式,它通过静态变量实现了全局只保证存在一个实例,保证了线程安全。但是,这种方式有一个明显的缺点,如果在程序某一次执行时一直没有用到这个实例,那就造成了资源的浪费,同时,使用全局变量也使程序变得难以调试与维护。
枚举方式:
public enum Singleton
//定义一个枚举的元素,它就是 Singleton 的一个实例
INSTANCE;
public void doSomething()
//使用方法
public class Test
public static void main(String[] args)
Singleton singleton = Singleton.INSTANCE;
singleton.doSomething();
延迟加载:
public class Singleton
private static Singleton instance;
private Singleton ()
public static Singleton getInstance()
//判断当前单例是否已经存在,若存在则返回,不存在则再建立单例
if (instance == null)
// 1
instance = new Singleton();
return instance;
上面创建单例是存在问题的,当一个线程走到 1 是,尚未来得及创建出对象,另一个线程也走到 1,就会打破单例,创建出多个对象。要解决线程安全问题,我们可以给 getInstance() 这个方法加一个 synchronized 关键字,或者 使用 synchronized() 修饰这段代码块,具体如下:
// 1.
public class Singleton
private static Singleton instance;
private Singleton ()
public static synchronized Singleton getInstance()
if (instance == null)
instance = new Singleton();
return instance;
// 2.
public class Singleton
private static Singleton instance;
private Singleton ()
public static Singleton getInstance()
synchronized(this)
if (instance == null)
instance = new Singleton();
return instance;
这样,我们就解决了线程安全的问题。但这样又会出现一个问题,每次调用 getInstance() 都会经过加锁这一层,会带来很多不必要的时间消耗,所以,我们在锁外在进行一次判断就会大大节省开支:
public class Singleton
private volatile static Singleton instance;
private Singleton ()
public static Singleton getInstance()
if (instance == null)
synchronized(this)
if (instance == null)
instance = new Singleton();
return instance;
这里,我们还加了 volatile 关键字来保证 对象在创建时,多线程对其的正确处理。这样,已经完全可以确保线程安全了。
工厂模式
简单工厂模式:
也叫静态工厂模式,客户传入不同的参数,就可以得到不同的对象。
// 产品接口:手机是产品,里面有个方法可以展示操作系统
public interface Phone
void showSystem();
// 具体产品 android or ios
public class AndroidPhone implements Phone
@Override
public void showSystem()
System.out.println("我是Android系统");
public class iOSPhone implements Phone
@Override
public void showSystem()
System.out.println("我是iOS系统");
// 工厂负责按需造手机
public class PhoneFactory
public static Phone create(String phone)
Phone mPhone;
switch (phone)
case "Android":
mPhone = new AndroidPhone();
break;
case "iOS":
mPhone = new iOSPhone();
break;
default:
throw new IllegalStateException("Unexpected value: " + phone);
return mPhone;
// 客户就可以得到想要的手机了
public class Customer
@Test
public void test()
// 来个Android的
Phone Android = PhoneFactory.create("Android");
Android.showSystem();
工厂方法模式:
是简单工厂模式的进一步深化,我们不再提供统一的工厂去创建对象,在工厂方法模式中,工厂类被抽象化,继而由它的子类去实现对象的实例化。这样我们在扩展工厂时就不会破坏开闭原则。
//工厂接口
public interface PhoneFactory
Phone create();
//工厂具体
public class AndroidFactory implements PhoneFactory
@Override
public Phone create()
return new AndroidPhone();
public class iOSFactory implements PhoneFactory
@Override
public Phone create()
return new iOSPhone();
//客户
public class Customer
@Test
public void test()
// 来一个Android的
AndroidFactory androidFactory = new AndroidFactory();
Phone android = androidFactory.create();
android.showSystem();
随着国产手机操作系统的崛起,我们是时候扩展扩展我们的工厂了:
//新增手机
public class HarmonyPhone implements Phone
@Override
public void showSystem()
System.out.println("我是鸿蒙的");
//新增工厂
public class HarmonyOSFactory implements PhoneFactory
@Override
public Phone create()
return new HarmonyPhone();
//客户
public class Customer
@Test
public void test()
// 来一个Android的
AndroidFactory androidFactory = new AndroidFactory();
Phone android = androidFactory.create();
android.showSystem();
// 来个鸿蒙的
HarmonyOSFactory harmonyOSFactory = new HarmonyOSFactory();
Phone harmony = harmonyOSFactory.create();
harmony.showSystem();
这就是工厂方法模式。但是随着我们产品的增多,代码量巨增。
抽象工厂模式:
抽象工厂模式又是工厂方法模式的扩展版,它不再创建一个单一的对象,而是创建一系列相关的对象。
继续拿上面的例子来说,手机除了操作系统,还分国产和进口。
//国产Android手机
public class ChinaAndroid implements AndroidPhone
@Override
public void showSystem()
System.out.println("国产Android");
//国产iOS手机
public class ChinaIOS implements iOSPhone
@Override
public void showSystem()
System.out.println("国产iOS");
//进口Android手机
public class ImportAndroid implements AndroidPhone
@Override
public void showSystem()
System.out.println("进口Android");
//进口iOS手机
public class ImportIOS implements iOSPhone
@Override
public void showSystem()
System.out.println("进口iOS");
//国产工厂
public class ChinaFactory implements PhoneFactory
@Override
public AndroidPhone createAndroid()
return new ChinaAndroid();
@Override
public iOSPhone createiOS()
return new ChinaIOS();
//进口工厂
public class ImportFactory implements PhoneFactory
@Override
public AndroidPhone createAndroid()
return new ImportAndroid();
@Override
public iOSPhone createiOS()
return new ImportIOS();
//客户
public class Customer
@Test
public void test()
// 国产工厂
PhoneFactory chinaFactory = new ChinaFactory();
AndroidPhone androidPhone = chinaFactory.createAndroid();
iOSPhone iOSPhone = chinaFactory.createiOS();
androidPhone.showSystem();
iOSPhone.showSystem();
OK,这就是抽象工厂模式。
介绍到这里,我们发现三种不同的方式存在着很多重叠的地方,而且,设计模式并不存在着明确的定义,关键在于要了解其中的核心思想。工厂模式的核心概念就是利用工厂来创建对象,而不应该将对象的创建交给一个和此对象无关的类,就上面例子而言,难道客户还要负责去自己造出一个手机吗?
建造者模式
正常的建造者模式
建造者模式允许用户在不知道内部构造的情况下,一步步精细控制对象的构造流程来创造出一个复杂对象。当我们构建不同的对象时,可以通过构造不同的建造者来进行实例化。
建造者包含以下类:
- Product(产品类):这是需要为它构建的类。
- Builder(抽象建造者类):用于声明需要构建产品的组成部分。
- ConcreteBuilder(具体建造者):实现抽象建造者中声明的方法。
- Director(指挥者):指导如何构建对象的类。
举个例子,构建一个程序员?
//产品类
public class Programmer
private int age;
private String language;
private int salary;
public void setAge(int age)
this.age = age;
public void setLanguage(String language)
this.language = language;
public void setSalary(int salary)
this.salary = salary;
public int getAge()
return age;
public int getSalary()
return salary;
public String getLanguage()
return language;
//抽象构建者
abstract class Builder
abstract void buildAge();
abstract void buildSalary();
abstract void buildlanguage();
//具体构建者
public class ConcreteBuilder extends Builder
Programmer programmer = new Programmer();
@Override
void buildAge()
programmer.setAge(25);
@Override
void buildSalary()
programmer.setSalary(20000);
@Override
void buildlanguage()
programmer.setLanguage("Java");
//指导类
public class Director
public void construct(Builder builder)
builder.buildAge();
builder.buildSalary();
builder.buildlanguage();
//Boss
public class Boss
@Test
public void test()
Director director = new Director();
ConcreteBuilder concreteBuilder = new ConcreteBuilder();
director.construct(concreteBuilder);
Programmer programmer = concreteBuilder.programmer;
System.out.println("age: " + programmer.getAge() + "\\n" +
"salary: " + programmer.getSalary() + "\\n" +
"language: " + programmer.getLanguage());
拥有方法链的匿名建造者:
我们再举一个例子
public class Computer
protected String mBoard;
protected String mDisplay;
protected String mCpu;
protected String mGpu;
protected String mOs;
public void setBoard(String board)
mBoard = board;
public void setDisplay(String display)
mDisplay = display;
public void setCpu(String cpu)
mCpu = cpu;
public void setGpu(String gpu)
mGpu = gpu;
public void setOs(String os)
mOs = os;
public static class Builder
Computer computer;
public Builder()
computer = new Computer();
public Builder board(String board)
computer.setBoard(board);
return this;
public Builder display(String display)
computer.setDisplay(display);
return this;
public Builder cpu(String cpu)
computer.setCpu(cpu);
return this;
public Builder gpu(String gpu)
computer.setGpu(gpu);
return this;
public Builder os(String os)
computer.setOs(os);
return this;
public Computer build()
return computer;
//使用方法
public void compyter()
Computer computer = new Computer.Builder()
.board("")
.display("")
.cpu("")
.gpu("")
.os("")
.build();
工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。
创建型模式还有原型模式和对象池模式,有时间我们再继续探究。
参考:《Java设计模式及实践》
以上是关于设计模式学习——创建型模式(单例工厂建造者)的主要内容,如果未能解决你的问题,请参考以下文章