静态/简单工厂

类图

工厂方法模式 - 图1

代码

AbstractProduct

  1. package cn.zjm404.stu.design.factory;
  2. public abstract class AbstractProduct {
  3. public void method1(){
  4. System.out.println("这是一个工厂模式中的产品");
  5. }
  6. public abstract void method2();
  7. }

ConcreteProduct1

  1. package cn.zjm404.stu.design.factory;
  2. public class ConcreteProduct1 extends AbstractProduct{
  3. @Override
  4. public void method2() {
  5. System.out.print("这是产品1");
  6. }
  7. }

ConcreteProduct2

  1. package cn.zjm404.stu.design.factory;
  2. public class ConcreteProduct2 extends AbstractProduct{
  3. @Override
  4. public void method2() {
  5. System.out.println("这是产品2");
  6. }
  7. }

Factory

方式一使用if语句判断

  1. package cn.zjm404.stu.design.factory.simple;
  2. import cn.zjm404.stu.design.factory.AbstractProduct;
  3. import cn.zjm404.stu.design.factory.ConcreteProduct1;
  4. import cn.zjm404.stu.design.factory.ConcreteProduct2;
  5. public class Factory {
  6. public static AbstractProduct create(String type){
  7. if(type.equalsIgnoreCase("1")){
  8. return new ConcreteProduct1();
  9. }else if(type.equalsIgnoreCase("2")){
  10. return new ConcreteProduct2();
  11. }else{
  12. return null;
  13. }
  14. }
  15. }

方式二使用反射创建

  1. public static <T extends AbstractProduct> AbstractProduct createPlus(Class<T> clazz){
  2. AbstractProduct ap = null;
  3. try{
  4. ap = (AbstractProduct) Class.forName(clazz.getName()).getConstructor().newInstance();
  5. } catch (IllegalAccessException | ClassNotFoundException | NoSuchMethodException e) {
  6. e.printStackTrace();
  7. } catch (InvocationTargetException e) {
  8. e.printStackTrace();
  9. } catch (InstantiationException e) {
  10. e.printStackTrace();
  11. }
  12. return ap;
  13. }

Client

  1. package cn.zjm404.stu.design.factory;
  2. import cn.zjm404.stu.design.factory.simple.Factory;
  3. import java.util.Scanner;
  4. public class Client {
  5. public static void main(String[] args) {
  6. String str;
  7. Scanner sc = new Scanner(System.in);
  8. str = sc.nextLine();
  9. AbstractProduct abstractProduct = Factory().create(str);
  10. if (abstractProduct != null) {
  11. abstractProduct.method2();
  12. }
  13. AbstractProduct ap = Factory.createPlus(ConcreteProduct1.class);
  14. ap.method2();
  15. }
  16. }

优缺点

可以很明显的看出
优点:高内聚,不暴露具体的产品类(使用反射除外)
确点:当有新产品出来时,需要去修改Factory类源码

工厂

介绍

每个对象都有对应的一个工厂,不对Client暴露具体的产品类

类图

关于依赖就只画有变量名的好了,例如:
在Client中
AbstractProduct ap = new ConcreteProduct1();
就只画
Client —> AbstractProduct
而不是
Client —> ConcreteProduct1
Client —> AbstractProduct 工厂方法模式 - 图2

代码

AbstractFactory

如果不需要有相同的方法,改为接口也可以

  1. package cn.zjm404.stu.design.factory.factory;
  2. import cn.zjm404.stu.design.factory.AbstractProduct;
  3. public abstract class AbstractFactory{
  4. public abstract AbstractProduct create();
  5. }

ConcreteFactory1

  1. package cn.zjm404.stu.design.factory.factory;
  2. import cn.zjm404.stu.design.factory.AbstractProduct;
  3. import cn.zjm404.stu.design.factory.ConcreteProduct1;
  4. public class ConcreteFactory1 extends AbstractFactory{
  5. @Override
  6. public AbstractProduct create() {
  7. return new ConcreteProduct1();
  8. }
  9. }

ConcreteFactory2

  1. package cn.zjm404.stu.design.factory.factory;
  2. import cn.zjm404.stu.design.factory.AbstractProduct;
  3. import cn.zjm404.stu.design.factory.ConcreteProduct1;
  4. public class ConcreteFactory1 extends AbstractFactory{
  5. @Override
  6. public AbstractProduct create() {
  7. return new ConcreteProduct1();
  8. }
  9. }

抽象工厂

介绍

与工厂方法模式类似,不同的是工厂可以生产多个相关联的产品,或者说生产一组产品,其余一样。有多少组产品,就有多少对应的工厂

  1. package cn.zjm404.stu.dp.creat.factory.af;
  2. public abstract class AbstractFactoryType1 {
  3. public abstract AbstractProductType1 creatProduct1();
  4. public abstract AbstractProductType1 creatProduct2();
  5. }

选择

三种工厂模式,如何选择呢?

  • 当产品生产逻辑简单时,使用简单工厂模式
    • 当产品逻辑较多时使用反射的形式创建
    • 较少时,使用if即可
  • 当产品生产逻辑较复杂时
    • 复杂且产品数量不多,工厂模式
    • 复杂且产品数量多并且产品间有共同点,抽象工厂模式