美文网首页
设计模式与架构02 -- 单例模式,工厂模式

设计模式与架构02 -- 单例模式,工厂模式

作者: YanZi_33 | 来源:发表于2021-12-01 17:48 被阅读0次

    单例模式

    • 单例模式是最简单的设计模式之一,属于创建型模式,它提供了一种创建对象的最佳方式;
    • 单例模式只涉及到一个单一的类,该类负责创建自己的对象,同时确保只会创建唯一的一个实例对象;
    单例模式的实现
    • 单例模式的实现分为两种:

      • 饿汉式:类加载就会导致该单实例对象被创建;
      • 懒汉式:类加载不会导致该单实例对象被创建,而是首次使用该对象时才会被创建;
    • 饿汉式单例模式 静态变量方式 案例代码如下:

    public class Singleton {
    
        //1.私有构造方法
        private Singleton() {}
    
        //2.在本类中创建实例对象
        private static Singleton instance = new Singleton();
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            return instance;
        }
    }
    
    • 饿汉式单例模式 静态代码块方式 案例代码如下:
    public class Singleton {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义静态成员变量
        private static Singleton instance;
    
        //3.在静态代码块中赋值
        static {
            instance = new Singleton();
        }
        
        public static Singleton getInstance() {
            return instance;
        }
    }
    
    • 饿汉式单例模式,在类加载时就已经创建单实例对象,若没有使用单例类,就会造成内存的浪费;

    • 懒汉式单例模式 - 线程不安全方式

    public class Singleton {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义静态成员变量
        private static Singleton instance;
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    • 懒汉式单例模式 - 线程安全方式
    public class Singleton {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义静态成员变量
        private static Singleton instance;
    
        //3.提供一个公共的访问方式,让外界访问
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }
    
    • synchronized:线程同步锁;

    • 懒汉式单例模式 - 双重检查锁方式

    public class Singleton {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义静态成员变量
        private static volatile Singleton instance;
    
        //3.提供一个公共的访问方式,让外界访问
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    • 添加volatile关键字之后的双重检查锁模式,是一种比较好的单例实现模式,能够保证在多线程的情况下,线程安全也不会有性能问题;

    • 懒汉式单例模式 - 静态内部类方式

    • 静态内部类单例模式中,实例有内部类创建,由于JVM在加载外部类的过程中,是不会加载静态内部类的,只有内部类的属性,方法被调用时才会被加载,并初始化其静态属性,静态属性由于被static修饰,保证只被实例化一次,并且严格保证实例化顺序;

    public class Singleton {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义一个静态内部类
        private static class SingletonHandler {
            //在内部类中声明并初始化外部类对象
            private static Singleton INSTANCE = new Singleton();
        }
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            return SingletonHandler.INSTANCE;
        }
    }
    
    • 第一次加载Singleton类时不会去初始化INSTANCE,只有第一次调用getInstance方法,虚拟机加载SingletonHandler类并初始化INSTANCE,这样不仅能确保线程安全,也能保证Singleton实例的唯一性;

    • 静态内部类单例模式时一种优秀的单例模式,是开源项目中比较常用的一种单例模式,在没有任何加锁的情况下,保证了多线程下的安全,并且没有任何性能影响和空间的浪费;

    • 饿汉式 -- 枚举方式

    • 枚举类实现单例模式是极力推荐的实现方式,因为枚举类型是线程安全的,并且只会加载一次,设计者充分利用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且枚举类型是所有单例实现中唯一不会被破坏的实现方式;

    public enum Singleton {
        INSTANCE;
    }
    
    • 序列化会破坏单例模式,使用上面创建的单例类,创建单例对象,枚举方式除外,案例代码如下:
    import java.io.Serializable;
    
    public class Singleton implements Serializable {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义一个静态内部类
        private static class SingletonHandler {
            //在内部类中声明并初始化外部类对象
            private static Singleton INSTANCE = new Singleton();
        }
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            return SingletonHandler.INSTANCE;
        }
    }
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //先写入文件
            try {
                writeObjectToFile();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            //两次读取文件的 获取的单例对象不同
            try {
                readObjectFromFile();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            try {
                readObjectFromFile();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //往文件中写数据
        public static void writeObjectToFile() throws Exception {
            Singleton singleton = Singleton.getInstance();
            //创建对象输出流对象
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/liyanyan33/Desktop/a.txt"));
            //写对象
            oos.writeObject(singleton);
            //释放资源
            oos.close();
        }
    
        //从文件中读数据
        public static void readObjectFromFile() throws Exception {
            //创建对象输入流对象
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/liyanyan33/Desktop/a.txt"));
            //读取对象
            Singleton singleton = (Singleton)ois.readObject();
            System.out.println(singleton);
            //释放资源
            ois.close();
        }
    }
    
    • 解决方案:在单例类中实现readResolve方法,原理在于Singleton singleton = (Singleton)ois.readObject(),底层会去判断调用readResolve方法,改进之后的代码如下所示:
    import java.io.Serializable;
    
    public class Singleton implements Serializable {
        //1.私有构造方法
        private Singleton() {}
    
        //2.定义一个静态内部类
        private static class SingletonHandler {
            //在内部类中声明并初始化外部类对象
            private static Singleton INSTANCE = new Singleton();
        }
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            return SingletonHandler.INSTANCE;
        }
    
        //当进行反序列化是 会自动调用改方法 将改方法的返回值直接返回
        public Object readResolve() {
            return SingletonHandler.INSTANCE;
        }
    }
    
    • 反射会破坏单例模式,使用上面创建的单例类(这里使用静态内部类的方式),创建单例对象,枚举方式除外,案例代码如下:
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //获取Singleton类的字节码对象
            Class clazz = Singleton.class;
            try {
                //获取无参构造方法
                Constructor cons = clazz.getDeclaredConstructor();
                //取消访问检查
                cons.setAccessible(true);
                //创建单例对象
                Singleton instance1 = (Singleton) cons.newInstance();
                Singleton instance2 = (Singleton) cons.newInstance();
                //不等 说明反射破坏了单例模式
                System.out.println(instance1 == instance2);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 解决方案:代码如下:
    public class Singleton  {
        
        private static boolean flag = false;
        
        //1.私有构造方法
        private Singleton() {
            //flag = true 表明非第一次访问
            //flag = false 表明第一次访问
            synchronized (Singleton.class) {
                if (flag) {
                    throw  new RuntimeException("不能创建多个对象");
                }
                flag = true;
            }
        }
    
        //2.定义一个静态内部类
        private static class SingletonHandler {
            //在内部类中声明并初始化外部类对象
            private static Singleton INSTANCE = new Singleton();
        }
    
        //3.提供一个公共的访问方式,让外界访问
        public static Singleton getInstance() {
            return SingletonHandler.INSTANCE;
        }
    }
    
    • 系统类RunTime就是一个单例模式类,源码如下:
    public class Runtime {
        private static Runtime currentRuntime = new Runtime();
    
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    
        /** Don't let anyone else instantiate this class */
        private Runtime() {}
    }
    
    • 其采用的是饿汉式 -- 静态成员变量 的单例模式;

    工厂模式

    • 首先我们通过一个实际案例,来慢慢引出工厂设计模式;
    • 设计一个咖啡店点餐系统,包含咖啡类与咖啡店类,UML类图如下:
    image.png
    • 代码实现如下:
    public abstract class Coffee {
    
        public abstract String getName();
    
        public void addMilk() {
            System.out.println("加奶");
        }
    
        public void addSugar() {
            System.out.println("加糖");
        }
    }
    
    public class AmericanCoffee extends Coffee{
        @Override
        public String getName() {
            return "美式咖啡";
        }
    }
    
    public class LatteCoffee extends Coffee{
        @Override
        public String getName() {
            return "拿铁咖啡";
        }
    }
    
    public class CoffeeStore {
        //点咖啡
        public Coffee orderCoffee(String type) {
            Coffee coffee = null;
            if (type.equals("american")) {
                coffee = new AmericanCoffee();
            } else if (type.equals("latte")) {
                coffee = new LatteCoffee();
            } else {
                throw new RuntimeException("对不起,您所点的咖啡没有!");
            }
            coffee.addMilk();
            coffee.addSugar();
            return coffee;
        }
    }
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            CoffeeStore coffeeStore = new CoffeeStore();
            coffeeStore.orderCoffee("latte");
        }
    }
    
    • 上述实现了点咖啡的功能,现在我们需要新增一种英式咖啡,创建英式咖啡类继承自Coffee类,但还需要改CoffeeStore类的代码,这就违背了软件设计原则中的开闭原则,如果我们使用工厂来生产对象,CoffeeStore类就只和工厂打交道就可以了,若要更换咖啡对象,直接在工厂里更换该咖啡对象即可,达到CoffeeStore类与具体咖啡对象解耦的目的,所以说工厂模式的最大优点是:解耦
    简单工厂模式
    • 简单工厂模式不是一种设计模式,不属于23种设计模式之一,其是一种编程习惯;
    • 简单工厂模式包含的角色有:
      • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能;
      • 具体产品:实现或者继承抽象产品的子类;
      • 具体工厂:提供了创建产品的方法,调用者通过该方法来创建产品;
    • 现在使用简单工厂模式对上面的案例进行改进,UML类图如下:
    image.png
    • 代码实现如下:
    public abstract class Coffee {
    
        public abstract String getName();
    
        public void addMilk() {
            System.out.println("加奶");
        }
    
        public void addSugar() {
            System.out.println("加糖");
        }
    }
    
    public class AmericanCoffee extends Coffee{
        @Override
        public String getName() {
            return "美式咖啡";
        }
    }
    
    public class LatteCoffee extends Coffee{
        @Override
        public String getName() {
            return "拿铁咖啡";
        }
    }
    
    public class SimpleCoffeeFactory {
        public Coffee createCoffee(String type) {
            Coffee coffee = null;
            if (type.equals("american")) {
                coffee = new AmericanCoffee();
            } else if (type.equals("latte")) {
                coffee = new LatteCoffee();
            } else {
                throw new RuntimeException("对不起,您所点的咖啡没有!");
            }
            return coffee;
        }
    }
    
    public class CoffeeStore {
        //点咖啡
        public Coffee orderCoffee(String type) {
            //创建工厂
            SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
            //通过工厂 获取咖啡
            Coffee coffee = factory.createCoffee(type);
    
            coffee.addMilk();
            coffee.addSugar();
            return coffee;
        }
    }
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            CoffeeStore coffeeStore = new CoffeeStore();
            coffeeStore.orderCoffee("latte");
        }
    }
    
    • 简单工厂模式的优点:

      • CoffeeStore类实现了与具体咖啡类的解耦;
      • SimpleCoffeeFactory工厂类封装了创建对象的细节,将创建对象与业务逻辑(点咖啡)分离,这样以后就避免了修改客户( CoffeeStore类)代码,如果要新增具体产品,可直接修改SimpleCoffeeFactory工厂类,更容易扩展;
    • 简单工厂模式的缺点:

      • SimpleCoffeeFactory工厂类与具体咖啡类产生了耦合,如果后期新增一种咖啡,SimpleCoffeeFactory工厂类也需要修改代码,违背了开闭原则;
      • CoffeeStore类SimpleCoffeeFactory工厂类产生耦合, CoffeeStore类可以看成是SimpleCoffeeFactory工厂类的客户,可能会有其他的客户类;
    • 在开发中,可以将简单工厂模式中创建对象的方法定义为静态方法,属于静态工厂模式,代码如下:

    public class SimpleCoffeeFactory {
        public static Coffee createCoffee(String type) {
            Coffee coffee = null;
            if (type.equals("american")) {
                coffee = new AmericanCoffee();
            } else if (type.equals("latte")) {
                coffee = new LatteCoffee();
            } else {
                throw new RuntimeException("对不起,您所点的咖啡没有!");
            }
            return coffee;
        }
    }
    
    public class CoffeeStore {
        //点咖啡
        public Coffee orderCoffee(String type) {
            //通过工厂 获取咖啡
            Coffee coffee = SimpleCoffeeFactory.createCoffee(type);
    
            coffee.addMilk();
            coffee.addSugar();
            return coffee;
        }
    }
    
    工厂方法模式
    • 针对上述案例的缺点,可使用工厂方法模式完美解决,完全遵循开闭原则;
    • 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪个产品对象,工厂方法使一个产品类的实例化延迟到其工厂的子类;
    • 工厂方法模式的角色:
      • 抽象工厂:提供创建产品的接口,调用者通过它访问具体工厂的工厂方法创建产品;
      • 具体工厂:主要是实现抽象工厂中抽象方法,完成具体产品的创建;
      • 抽象产品:定义了产品的规范接口,描述了产品的主要特性和功能;
      • 具体产品:实现了抽象产品定义的规范接口,由具体工厂来创建,它与具体工厂之间一一对应;
    • 使用工厂方法模式对上述案例进行改进,UML类图如下:
    image.png
    • 代码实现如下:
    //抽象产品类
    public abstract class Coffee {
        public abstract String getName();
    
        public void addMilk() {
            System.out.println("加奶");
        }
    
        public void addSugar() {
            System.out.println("加糖");
        }
    }
    
    //具体产品类
    public class AmericanCoffee extends Coffee{
        @Override
        public String getName() {
            return "美式咖啡0";
        }
    }
    
    //具体产品类
    public class LatteCoffee extends Coffee{
        @Override
        public String getName() {
            return "拿铁咖啡";
        }
    }
    
    //抽象工厂
    public interface CoffeeFactory {
        public Coffee createCoffee();
    }
    
    //具体工厂类
    public class AmericanCoffeeFactory implements CoffeeFactory{
        @Override
        public Coffee createCoffee() {
            return new AmericanCoffee();
        }
    }
    
    //具体工厂类
    public class LatteCoffeeFactory implements CoffeeFactory{
        @Override
        public Coffee createCoffee() {
            return new LatteCoffee();
        }
    }
    
    //客户端
    public class CoffeeStore {
        //持有抽象工厂
        private CoffeeFactory factory;
    
        public void setFactory(CoffeeFactory factory) {
            this.factory = factory;
        }
    
        public Coffee orderCoffee() {
            Coffee coffee = factory.createCoffee();
            coffee.addSugar();
            coffee.addMilk();
            return coffee;
        }
    }
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            CoffeeStore store = new CoffeeStore();
            //在使用是初始化具体的工厂
            AmericanCoffeeFactory acf = new AmericanCoffeeFactory();
            store.setFactory(acf);
            store.orderCoffee();
        }
    }
    
    • 现在再新增一款咖啡,只需要创建一个具体工厂类和具体产品类,不会修改抽象工厂类和抽象产品了,符合开闭原则;
    • 工厂方法模式的优点:
      • 客户只需要知道具体工厂 就能获取到想要的具体产品,无需知道产品创建的细节;
      • 在系统新增产品时,只需要新增具体工厂类和具体产品类,无需对原工厂进行修改,满足开闭原则;
    • 工厂方法模式的缺点:
      • 每新增产品时, 都要新增具体工厂类和具体产品类,增加系统的复杂度;
    抽象工厂模式
    • 产品类型:具体产品的抽象,例如拿铁咖啡与美式咖啡都属于咖啡;
    • 产品族:具体产品的抽象集合,例如咖啡与甜点构成一个产品族;
    • 抽象工厂模式是工厂方法模式的升级版,工厂方法模式只生产一种类型的产品,而抽象工厂模式可生产多个不同类型的产品;
    • 抽象工厂模式提供了一个 创建一组相关或相互依赖对象 的接口,且访问类无需指定具体产品类 就能获取到不同类型产品的模式结构;
    • 抽象工厂模式的角色有:
      • 抽象工厂:提供创建产品的接口,它包含多个创建产品的方法,可以创建多个不同类型的产品;
      • 具体工厂:主要是实现抽象工厂中多个抽象方法,完成具体产品的创建;
      • 抽象产品:定义了产品的规范接口,描述了产品的主要特性和功能,有多个抽象产品类;
      • 具体产品:实现了抽象产品定义的规范接口,由具体工厂来创建,它与具体工厂之间是多对一的关系;
    • 场景案例:现在咖啡店业务发生了变化,不仅要生产咖啡还要生产甜点,如提拉米苏,抹茶慕斯等,如果按照工厂方法模式进行设计,需要定义提拉米苏类,提拉米苏工厂类,抹茶慕斯类,抹茶慕斯工厂类以及甜品抽象类,出现类爆炸情况,其中拿铁咖啡与美式咖啡属于同一产品类型,提拉米苏与抹茶慕斯属于同一产品类型,拿铁咖啡与提拉米苏属于同一产品族假设属于(意大利风味),美式咖啡与抹茶慕斯属于同一产品族假设属于(美式风味),可采用抽象工厂模式,UML类图如下:
    image.png
    • 代码实现如下:
    //咖啡抽象类
    public abstract class Coffee {
        public abstract String getName();
    
        public void addMilk() {
            System.out.println("加奶");
        }
    
        public void addSugar() {
            System.out.println("加糖");
        }
    }
    
    //具体产品类
    public class AmericanCoffee extends Coffee{
        @Override
        public String getName() {
            return "美式咖啡";
        }
    }
    
    //具体产品类
    public class LatteCoffee extends Coffee{
        @Override
        public String getName() {
            return "拿铁咖啡";
        }
    }
    
    //甜点抽象类
    public abstract class Dessert {
        abstract public void show();
    }
    
    //具体产品类
    public class Trimisu extends Dessert{
        @Override
        public void show() {
            System.out.println("提拉米苏");
        }
    }
    
    //具体产品类
    public class MachaMourse extends Dessert{
        @Override
        public void show() {
            System.out.println("抹茶慕斯");
        }
    }
    
    //抽象工厂类
    public interface DessertFactory {
        public Coffee createCoffee();
        public Dessert createDessert();
    }
    
    //具体工厂类
    public class AmericanDessertFactory implements DessertFactory{
        @Override
        public Coffee createCoffee() {
            return new AmericanCoffee();
        }
    
        @Override
        public Dessert createDessert() {
            return new MachaMourse();
        }
    }
    
    //具体工厂类
    public class ItalyDessertFactory implements DessertFactory{
        @Override
        public Coffee createCoffee() {
            return new LatteCoffee();
        }
    
        @Override
        public Dessert createDessert() {
            return new Trimisu();
        }
    }
    
    //客户端
    public class CoffeeStore {
    
        private DessertFactory factory;
    
        public void setFactory(DessertFactory factory) {
            this.factory = factory;
        }
    
        public Coffee orderCoffee() {
            Coffee coffee = null;
            coffee = factory.createCoffee();
            coffee.addSugar();
            coffee.addMilk();
            return coffee;
        }
    
        public Dessert orderDessert() {
            Dessert dessert = null;
            dessert = factory.createDessert();
            dessert.show();
            return dessert;
        }
    }
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            CoffeeStore store = new CoffeeStore();
            AmericanDessertFactory factory = new AmericanDessertFactory();
            store.setFactory(factory);
            store.orderCoffee();
            store.orderDessert();
        }
    }
    
    • 如果要新增一个产品族,只需要再加一个对应的工厂类,不需要修改其他类;
    • 抽象工厂模式的优点:
      • 当产品族中的多个对象,被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象;
    • 抽象工厂模式的缺点:
      • 当产品族中需要新增一个新的产品时,所有的工厂类都需要进行修改;
    • 抽象工厂模式的使用场景:
      • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,例如电器工厂中的电视机,洗衣机,空调等;
      • 系统中有多个产品族,但每次只使用其中的某一产品族时;
      • 系统中提供了产品的类库,且所有产品的接口都相同,客户端不依赖产品实例的创建细节与内部结构;
    工厂模式的扩展
    • 可以通过简单工厂模式 + 配置文件的方式 解除工厂对象和产品对象的耦合,在工厂类中加载配置文件中的全类名,并创建对象进行存储,客户端如果需要对象,直接进行获取即可;
    • 第一步:定义配置文件,命名为bean.properties,文件内容如下:
    american=com.example.sign.AmericanCoffee
    latt=com.example.sign.LatteCoffee
    
    • 代码编写:
    public class SimpleCoffeeFactory {
    
        //加载配置文件 获取配置文件中类名,并创建该对象进行存储
        //1.定义容器 存储对象
        private static HashMap<String,Coffee> map = new HashMap<>();
        //2.加载配置文件
        static {
            Properties p = new Properties();
            InputStream is = SimpleCoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            //调用p的load方法 进行配置文件加载
            try {
                p.load(is);
                //从p集合中获取类名 创建对象
                Set<Object> keys = p.keySet();
                for (Object key: keys) {
                    String className = p.getProperty((String) key);
                    //通过反射技术创建对象
                    Class clazz = Class.forName(className);
                    Coffee coffee = (Coffee) clazz.newInstance();
                    //将名称与对象 存储到容器中
                    map.put((String) key,coffee);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static Coffee createCoffee(String name) {
            //通过名称 获取对象
            return map.get(name);
        }
    }
    
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            CoffeeStore store = new CoffeeStore();
            Coffee coffee = store.orderCoffee("latte");
            System.out.println(coffee.getName());
        }
    }
    
    • 静态成员变量map 用来存储创建的对象,新增一种对象时,只需要修改配置文件即可;

    相关文章

      网友评论

          本文标题:设计模式与架构02 -- 单例模式,工厂模式

          本文链接:https://www.haomeiwen.com/subject/ferjxrtx.html