工厂方法模式

这个什么是工厂方法模式呢?

  工厂方法模式使用的频率非常高,在我们日常的开发中总能见到他的身影。其定义为:
  Define an interface for creating an object,but let subclasses decide which class to instanitate Factory Method lets a class defer instantiation to subclasses
  (定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类)

  也可以这样理解:

   工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Java论坛 ,就大量使用了工厂模式工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

  其UML图

 

  首先来看一个有意思的小故事。就是这个女娲那个时代觉得一个人太无聊了,就想造几个和自己差不多的东西来做伴。

  于是女娲就用她的八卦炉来生产我们人类。

  在这个过程中涉及三个对象:女娲,八卦炉,不同的人。女娲就类似一个客户,八卦炉就是一个工厂,而人就是产品

  来让我们用代码来实现这个造人计划

  First

  人类的总称:

package com;

public interface Human {
    //每个人种的皮肤都有相应的颜色
    public void getColor();
    //人类会说话
    public void talk();
}

//不同的人
package com;
public class WhiteHuman implements Human { @Override public void getColor() { System.out.println("这是白种人的颜色"); } @Override public void talk() { System.out.println("这是白种人说的话"); } }
package com;
//黄种人
public class YellowHuman implements Human {

    @Override
    public void getColor() {
        System.out.println("这是黄种人的颜色");
        
    }

    @Override
    public void talk() {
        System.out.println("这是黄种人说的话");
        
    }

}

然后来创建工厂

package com;

/*
 * 作为一个生产者来说,我们只要知道生产了什么,而不需要事物的具体信息。
 * 通过分析,我们发现八卦炉生产人类的方法输入参数类型应该是Human接口的实现类
 */
public abstract class AbstractHumanFactory {
    public abstract <T extends Human> T createHuman(Class<T> c);
}

实现抽象工厂的人工类

package com;

public class HumanFactory extends AbstractHumanFactory{

    @Override
    public <T extends Human> T createHuman(Class<T> c) {
        //定义一个生产人种
        Human human=null;
        
        try {
            //产生一个人
            human=(Human)Class.forName(c.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) human;
    }
    
}

测试类

package com;

public class NvWa {
    public static void main(String[] args){
        //声明阴阳八卦炉
        AbstractHumanFactory YinYangLu=new HumanFactory();
        System.out.println("生产白人");
        Human whiteman=YinYangLu.createHuman(WhiteHuman.class);
        whiteman.getColor();
        whiteman.talk();
    }
    

}

这是一个工厂的通用源码

//抽象产品类
    public abstract class Product{
        public void method1(){
            
        }
        
        public abstract void method2();
    }
    
    //具体产品类1
    public class ConcreteProduct1 extends Product{

        @Override
        public void method2() {
            //业务逻辑
        }
    }
    //具体产品类2
    public class ConcreteProduct2 extends Product{
        @Override
        public void method2() {
            //业务逻辑
        }
        
    }
    
    //抽象工厂类
    public abstract class Cretor{
        /*
         * 创建一个产品对象,其输入参数类型可以自行设置
         * 通常String,Enum,Class 等,当然也可以为空
         */
        public abstract <T extends Product> T createProduct(Class<T> c);
        
    }
    
    //具体工厂类
    public class ConcreteCreator extends Cretor{

        @Override
        public <T extends Product> T createProduct(Class<T> c) {
            Product product=null;
            try {
                product=(Product)Class.forName(c.getName()).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return (T) product;
        }
        
    }
    
    //场景类
    public  class Client{
        public static void main(String[] args){
            Cretor creator=new ConcreteCreator();
            Product product=creator.createProduct(ConcreteProduct1.class);
        }
    }
        

优点:
·  首先,良好的封装性,代码结构清晰。一个对象创建时有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,
  不用知道创建对象的艰辛过程,降低了模块间的耦合性

  其次,工厂方法模式的扩展性非常优秀,只要适当的修改工厂类或扩展一个工厂类,就可以完成”拥抱变化“

  再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化

  最后,工厂方法模式是典型的解耦和性框架

posted @ 2016-06-21 00:01  Animationer  阅读(229)  评论(0编辑  收藏  举报