专栏首页李蔚蓬的专栏Java设计模式 | 工厂模式解析与实战

Java设计模式 | 工厂模式解析与实战

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类。

工厂方法模式的使用场景

在任何需要生成复杂对象的地方,都可以使用工厂方法模式 复杂对象适合使用工厂模式, 简单用new就可以完成创建的对象无需使用工厂模式

工厂方法模式的UML类图

● 抽象工厂,其为工厂方法模式的核心; ● 具体工厂,其实现了具体的业务逻辑; ● 抽象产品,工厂方法模式所创建的产品的父类; ● 具体产品,为实现抽象产品的某个具体产品的对象。

实战【下面demo主要有三种形式】

最简单的,只生产一种类型实例的写法:

    public abstract class Product {
        /**
         * 产品类的抽象方法
         *由具体的产品类去实现
         */
        public abstract void method();
    }
    //具体产品类A
    public class ConcreteProductA extends Product {
        @Override
        public void method() {
            System.out.println("我是具体的产品A");
        }
    }
    //具体产品类B
    public class ConcreteProductB extends Product {
        @Override
        public void method() {
            System.out.println("我是具体的产品B");
        }
    }

    //抽象工厂类
    public abstract class Factory {
        /**
         * 抽象工厂方法
         * 具体生产什么由子类去实现
         *
         * @return 具体的产品对象
         */
        public abstract Product createProduct();
    }
    //具体工厂类
    public class ConcreteFactory extends Factory {
        @Override
        public Product createProduct() {
            return new ConcreteProductA();
        }
    }

    //客户类
    public class Client {
        public static void main(String[] args) {
            Factory factory = new ConcreteFactory();
            Product p = factory.createProduct();
            p.method();
        }
    }

上面是生产产品A,如果要生产产品B,则手动修改工厂方法:

public class ConcreteFactory extends Factory {
        @Override
        public Product createProduct() {
            return new ConcreteProductB();
            // return new ConcreteProductA();
        }
    }

以上这种方式比较不灵活,不优雅,只是比较简单, 如果要生产的产品只有一种,就可以这样写; 但是如果要生产的产品有多种, 则建议用以下的动态写法!!!!!!! 通过反射、泛型来实现^^^^^^^^^^^^^^^^^^

public abstract class Factory {
        /**
         * 抽象工厂方法
         * 具体生产什么由子类去实现
         *
         * @param clz 产品对象类类型
         *
         * @return 具体的产品对象
         */
        public abstract <T extends Product> T createProduct(Class<T> clz);
    }

对于具体的工厂类,则通过反射获取类的示例即可:

public class ConcreteFactory extends Factory {
        @Override
        public <T extends Product> T createProduct(Class<T> clz) {
            Product p = null;
            try {
                p = (Product) Class.forName(clz.getName()).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return (T) p;
        }
}

最后再来看看Client中的实现:

public class Client {
        public static void main(String[] args) {
            Factory factory = new ConcreteFactory();
            Product p = factory.createProduct(ConcreteProductB.class);
            p.method();
        }
    }

需要哪一个类的对象就传入哪一个类的类型即可, 这种方法比较简洁、动态; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 【只有一个具体工厂类 所有产品的构建 都挤在一个createProduct()中完成!】 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

而前面的两种工厂方法模式, 即如果确定工厂类只有一个,也可以简化掉抽象类!!!!!!!!!!! 将对应的工厂方法改为静态方法即可: (这样的方式又称为简单工厂模式或静态工厂模式, 它是工厂方法模式的一个弱化版本) 这里只剩下三个元素,抽象 / 具体产品类工厂类

简单工厂模式 / 静态工厂模式

public class Factory {
        public static Product createProduct() {
            //构建逻辑
            return new ConcreteProductB();

            // return new ConcreteProductA();
        }
}

-------------------------------------------
//泛型
public class Factory {
        
        public <T extends Product> T createProduct(Class<T> clz) {
            Product p = null;
            try {
                p = (Product) Class.forName(clz.getName()).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return (T) p;
        }
}

或者也可以用另外的形式, 尝试为每一个产品都定义一个具体的工厂,各司其职: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 【与上面的形式相比, 这里拥有多个具体工厂类 每个工厂类各自封装对应产品的createProduct();】 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

多工厂方法模式

public class ConcreteFactoryA extends Factory {
        @Override
        public Product createProduct() {
            return new ConcreteProductA();
        }
}

public class ConcreteFactoryB extends Factory {
        @Override
        public Product createProduct() {
            return new ConcreteProductB();
        }
}

public class Client {
        public static void main(String[] args) {
            Factory factoryA = new ConcreteFactoryA();
            Product productA = factoryA.createProduct();
            productA.method();
            Factory factoryB = new ConcreteFactoryB();
            Product productB = factoryB.createProduct();
            productB.method();
        }
    }

像这样拥有多个工厂的方式称为多工厂方法模式

工厂方法模式是完全符合设计原则的,其降低了对象之间的耦合度,而且,工厂方法模式依赖于抽象的架构,其将实例化的任务交由子类去完成,有非常好的扩展性。


参考:

  • 《Android源码设计模式解析与实战》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Binary XML file line #19: Attempt to invoke virtual method 'boolean java.lang.String.equals(java....

    APP中需要实现LayoutInflater布局加载器动态加载布局,然而开启程序一运行就闪退。。。

    凌川江雪
  • NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet...

    NoSuchMethodException: <init> [class android.content.Context, interface android....

    凌川江雪
  • PHPstudy | 使用站点管理器来创建虚拟主机

    可以看到 http://localhost/index.php 这个地址,localhost 这个地址是在 hosts 文件中定义的,

    凌川江雪
  • 初级工程师面试答案

    一、选择题:(每题1分,共65分,包含复选题和单选题,复选题已做标记,其余为单选题)

    Java架构师必看
  • 基础拾遗------------依赖注入

    前言   好久没有写微博了,因为前段时间由于家庭原因决定从工作了3年多的北京转移到上海去。依赖注入在学习net core的时候也有写过类似的东西,只是实践的较少...

    kmonkey
  • 小朋友学Java(9):抽象类与接口

    之前提过面向对象有三大特性:封装、继承、多态。 还有另一种说法,即面象对象有四大特性:抽象、封装、继承、多态。 这两种说法都是对的,不必拘泥于哪种说法。关键要能...

    海天一树
  • C# 极限压缩 dotnet core 控制台发布文件

    每次发布 dotnet core 应用都会觉得发布文件太大,而如果使用极限压缩,用 CoreRT 能让发布的控制台文件到 5KB 左右,不需要带框架就能在其他设...

    林德熙
  • java动态代理

          5. 调用上述生成的class UserService.java 是接口 UserServiceImpl.java是被代理对象 实现了Us...

    曼路
  • 【设计模式】—— 适配器模式Adapter

      模式意图   如果已经有了一种类,而需要调用的接口却并不能通过这个类实现。因此,把这个现有的类,经过适配,转换成支持接口的类。   换句话说,就是把一种现有...

    用户1154259
  • 【Java学习笔记之二十一】抽象类在Java继承中的用法小结

    一、抽象类的基本概念 普通类是一个完善的功能类,可以直接产生实例化对象,并且在普通类中可以包含有构造方法、普通方法、static方法、常量和变量等内容。而抽象类...

    Angel_Kitty

扫码关注云+社区

领取腾讯云代金券