设计模式学习——创建型模式(单例工厂建造者)

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设计模式及实践》

以上是关于设计模式学习——创建型模式(单例工厂建造者)的主要内容,如果未能解决你的问题,请参考以下文章

设计模式-创建型模式讲解(单例原型工厂方法抽象工厂建造者)

创建型设计模式

设计模式简单工厂模式

编程经常使用设计模式具体解释--(上篇)(工厂单例建造者原型)

23种设计模式介绍以及单例模式的学习

chatGPT教你设计模式[3] ——创建型模式(单例模式建造者模式和原型模式)