设计模式·工厂模式

1.工厂模式定义

工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。


工厂模式通用类图
  • Creator:抽象工厂类,定义了创建对象的手抽象方法
  • ConcreteCreator:集体的创建对象的工厂类
  • Product:要创建对象的抽象类
  • ConcreteProduct:要创建的对象
代码实现
public abstract class Creator {
    /**
     * 创建产品类,阐述类型可以为Class,String,Enum,也可以为空
     *
     * @param c
     * @param 
     * @return
     */
    public abstract  T createProduct(Class c);
public class ConcreteCreator extends Creator {
    @Override
    public  T createProduct(Class c) {
        Product product = null;
        try {
            product = (Product) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) product;
    }
}
public abstract class Product {
    public void method1() {
        System.out.println("产品类的公共方法");
    }

    //抽象方法
    public abstract void method2();
}
public class ConcreteProduct1 extends Product {
    @Override
    public void method2() {
        System.out.println("产品ConcreteProduct1.method2()");
    }
}
...
public class ConcreteProduct2 extends Product{
    @Override
    public void method2() {
        System.out.println("产品ConcreteProduct2.method2()");
    }
}

使用场景类

public class Main {
    public static void main(String[] args) {
        Creator creator = new ConcreteCreator();
        Product product1 = creator.createProduct(ConcreteProduct1.class);
        Product product2 = creator.createProduct(ConcreteProduct2.class);
        product1.method1();
        product2.method1();
        product1.method2();
        product2.method2();
    }
}
2.工厂方法模式的变种
2.1 简单工厂

一个模块仅需要一个工厂,没有必要创建一个抽象的工厂类

public class ProductFactory {

    public static  T createProduct(Class c) {
        Product product = null;
        try {
            product = (Product) Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) product;
    }
}
2.2 多工厂

在一些复杂的业务场景下,一个抽象产品有多个具体的产品类,每个具体的产品他的初始化过程又各不一样,除了new构造方法外还要设置一些初始化值等,如果这些产品都放在工厂类里面初始化就会造成工厂类的代码结构不清晰,所以通过多个工厂可以比较好的处理这个问题

多工厂类图

代码实现如下

public class Product1Factory extends Factory {

    @Override
    public Product1 createProduct() {
        return new Product1();
    }
}
public class Product2Factory extends Factory {

    @Override
    public Product2 createProduct() {
        return new Product2();
    }
}
2.3 工厂单例

通过工厂模式创建单例,具体的产品类定义为私有构造方法,工厂类通过反射生产该产品的全局唯一对象,也是单例的一种实现方式。

public class Singleton {
    private Singleton() {
    }

    public void doSomething() {

    }
}
public class SingletonFactory {
    private static Singleton singleton;

    static {
        try {
            Class cl = Class.forName(Singleton.class.getName());
            Constructor constructor = cl.getDeclaredConstructor();
            constructor.setAccessible(true);
            singleton= (Singleton) constructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Singleton getSingleton() {
        return singleton;
    }
}

测试一下在如下多线程中创建单例对象并打印hashCode会发现都是同一个对象值

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Singleton singleton = SingletonFactory.getSingleton();
                    System.out.println(singleton.hashCode());
                }
            }).start();
        }
    }
}

输出结果都为

1458268403
1458268403
...
1458268403
2.4 延迟加载工厂类

定义一个map存放所有的Product,如果map中有则直接返回对应的产品,没有则生产产品并存入map中

public class ProductFactory {
    private static final Map productMap = new HashMap<>();

    private static synchronized Product createProduct(String type) {
        Product product = null;
        if (productMap.containsKey(type)) {
            product = productMap.get(type);
        } else {
            if (type.equals("product1")) {
                product = new Product1();
            } else if (type.equals("product2")) {
                product = new Product2();
            }
            productMap.put(type, product);
        }
        return product;
    }
}

你可能感兴趣的:(设计模式·工厂模式)