美文网首页Android设计模式
创建型设计模式——工厂方法模式

创建型设计模式——工厂方法模式

作者: 忘尘无憾 | 来源:发表于2017-12-28 17:02 被阅读6次

    定义

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

    关键点

    • 创建型设计模式之一
    • 工厂方法模式又称工厂模式、多态工厂模式和虚拟构造器模式
    • 通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象
    工厂方法UML图
    • 抽象工厂(Factory),为工厂方法模式的核心
    • 具体工厂(Concrete Factory),实现了具体的业务逻辑
    • 抽象产品(Product),是工厂方法模式所创建的产品的父类
    • 具体产品(Concrete Product),为实现抽象产品的某个具体产品对象

    使用场景

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

    场景例子说明

    • 抽象产品类
    public abstract class Product {
        /**
         * 抽象产品类的抽象方法
         * <br/>
         * 由具体的产品类去实现
         */
        public abstract void showProduct();
    }
    
    • 具体产品类
    // 具体产品类A
    public class ProductA extends Product {
        @Override
        public void showProduct() {
            System.out.println("我是具体的产品类A");
        }
    }
    
    // 具体产品类B
    public class ProductB extends Product {
        @Override
        public void showProduct() {
            System.out.println("我是具体的产品类B");
        }
    }
    
    • 抽象工厂类
    public abstract class Factory {
        /**
         * 抽象工厂方法
         * <br/>
         * 具体生产什么交给子类去做
         * @return
         */
        public abstract Product createProduct();
    }
    
    • 具体工厂类
    public class JFactory extends Factory {
        @Override
        public Product createProduct() {
            return new ProductA();
        }
    }
    
    • 测试
    public class FactoryTest {
        public static void main(String[] args) {
            Factory factory = new JFactory();
            Product product = factory.createProduct();
            product.showProduct();
        }
    }
    
    //结果
    我是具体的产品类A
    

    若是想生产产品类B,则可以将具体工厂类修改如下:

    public class JFactory extends Factory {
        @Override
        public Product createProduct() {
            return new ProductB();
        }
    }
    
    // 结果
    我是具体的产品类B
    
    通过反射的方式

    在我们具体的工厂中,想要生产那个具体的产品就可以生成具体的产品,但是每次都需要修改具体工厂的内容。如果采用反射的方式,则可以更为简洁地来生产具体产品。

    只需要在工厂方法中的参数列表传入一个Class类来决定是哪一个产品类即可。

    // 抽象工厂类
    public abstract class FS_Factory {
        /**
         * 抽象工厂方法
         * <br/>
         * 具体生产什么由子类去实现
         * @param clz 产品对象类型
         * @param <T> 
         * @return
         */
        public abstract <T extends Product> T createPruduct(Class<T> clz);
    }
    
    // 具体工厂类
    public class FS_JFactory extends FS_Factory {
    
        @Override
        public <T extends Product> T createPruduct(Class<T> clz) {
            Product product = null;
            try {
                product = (Product) Class.forName(clz.getName()).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return (T) product;
        }
    
    // 测试
    public class FactoryTest {
        public static void main(String[] args) {
            FS_Factory fs_factory = new FS_JFactory();
            Product product1 = fs_factory.createPruduct(ProductB.class);
            product1.showProduct();
    
        }
    }
    // 结果
    我是具体的产品类B
    

    从上可以知道,通过反射可以需要哪个对象就传入哪个对象的类型即可,这种方式比较简洁、动态。

    多工厂方法模式

    如果觉得上述反射的方式比较复杂,不易理解,也可以尝试为每个产品单独定义具体的工厂,各司其职。这种方法被称为多工厂方法模式。

    public class JFactoryA extends Factory {
        @Override
        public Product createProduct() {
            return new ProductA();
        }
    }
    public class JFactoryB extends Factory {
        @Override
        public Product createProduct() {
            return new ProductB();
        }
    }
    
    简单工厂模式(静态工厂模式)

    假设当我们只有一个工厂,那么其实无需抽象工厂类,可以将其简化。同时将简化的工厂里的工厂方法改为静态方法即可。这种方式则被称为简单工厂模式,实际上是工厂方法模式的弱化版本。

    // 简单工厂类
    public class JD_Factory {
        public static Product createProduct() {
            return new ProductA();
        }
    }
    
    // 测试
    public class FactoryTest {
        public static void main(String[] args) {
            Product product2 = JD_Factory.createProduct();
            product2.showProduct();
    
        }
    }
    
    // 结果
    我是具体的产品类A
    

    工厂方法的优缺点

    优点

    • 降低了对象间的耦合性
    • 对调用者隐藏了产品的生产过程
    • 易于拓展

    缺点

    • 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销。
    • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。



    引用
    《Android源码设计模式解析与实战》
    Android设计模式(四)- 工厂方法模式
    [Android]三种工厂模式总结。

    相关文章

      网友评论

        本文标题:创建型设计模式——工厂方法模式

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