PerKins Zhu

Le vent se lève,il faut tenter de vivre.

导航

设计模式—简单工厂

Posted on 2016-08-27 19:38  PerKins.Zhu  阅读(334)  评论(0编辑  收藏  举报

工厂模式:使用者不用创建使用对象,直接从工厂取出对象进行使用。

示例:子宫(工厂)创造各种动物

  工厂模式的优势:在添加动物的时候不需要修改客户端(TestFactoryPattern),只需要直接添加动物就可以,工厂会自动(这时需要一个标示告诉工厂你需要那种动物,也就是type)返回需要的动物。

工厂模式类图:

直接代码:

定义一个抽象类Animal,定义动物的共同属性 name,speed,共同行为:say(),run();,子类可进行覆写方法实现自己特有的行为。

package com.zpj.designMode;
/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:11:07
 * @version :1.1
 * 
 */
public abstract class Animal {
    public String name;
    public int speed;
    public abstract void run();
    public abstract void say();
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }
}

 

下面添加三个动物:Person  Tiger ,Panda

package com.zpj.designMode;

/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:13:48
 * @version :1.1
 * 
 */
public class Person extends Animal {

    public Person() {
    }

    public Person(String name, int speed) {
        this.name = name;
        this.speed = speed;
    }

    @Override
    public void run() {
        System.out.println(name + "--两条腿跑---speed:" + speed + "KM/h");
    }

    @Override
    public void say() {
        System.out.println(name + "--嘴说--- hello , i am " + name);
    }
}

 

 

package com.zpj.designMode;

/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:18:45
 * @version :1.1
 * 
 */
public class Tiger extends Animal {

    
    public Tiger() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Tiger(String name, int speed) {
        super();
        this.name = name;
        this.speed = speed;
    }

    public void run() {
        System.out.println(name + "--四条腿窜---speed:" + speed);
    }

    public void say() {
        System.out.println(name + "--吼--- hello , i am " + name);
    }

}

 

 

package com.zpj.designMode;
/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:17:45
 * @version :1.1
 * 
 */
public class Panda extends Animal{

    
    public Panda() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Panda(String name,int speed) {
        this.name = name;
        this.speed = speed;
    }

    public void run() {
        System.out.println(name + "--四条腿爬---speed:" + speed);
    }

    public void say() {
        System.out.println(name + "--不知道--- hello , i am " + name);
    }

}

 

 

创建个子宫(工厂)生产动物

package com.zpj.designMode;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;

/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:21:38
 * @version :1.1
 * 
 */
public class Uterus {

    public static Animal createAnimal(int type) {//type 类型告诉工厂客户端需要什么动物
        switch (type) {
        case 1:
            return new Person("所谓的高级动物", 30);
        case 2:
            return new Tiger("老虎", 100);
        case 3:
            return new Panda("黑白猫", 10);
        }
        return null;
    }

    public static Animal createAnimal() throws Exception {
        //从配置文件中读出客户端需要什么动物
        Properties prop = new Properties();
        InputStream in = Object.class.getResourceAsStream("/com/zpj/designMode/animal.properties");
        try {
            prop.load(in);
            String type = prop.getProperty("type").trim();
            String name = prop.getProperty("name").trim();
            String speed = prop.getProperty("speed").trim();
            //使用反射机制生成客户端需要的动物
            Class classs = Class.forName(type);
            Animal animal = (Animal) classs.newInstance();
            animal.setName(name);
            animal.setSpeed(Integer.parseInt(speed));
            return animal;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

测试类:

package com.zpj.designMode;

import org.junit.Test;

/**
 * @author PerKins Zhu
 * @date:2016年8月27日 下午5:39:35
 * @version :1.1
 * 
 */
public class TestFactoryPattern {

    @Test
    public void test01() throws Exception {
        Animal animal;
        for (int i = 1; i < 4; i++) {
            System.out.println("-----------------test:" + i + " -------------------");
            animal = Uterus.createAnimal(i);
            animal.say();
            animal.run();
        }
    }

    //使用配置文件告诉工厂需要什么动物
    @Test
    public void test02() throws Exception {
        Animal animal;
        animal = Uterus.createAnimal();
        animal.say();
        animal.run();
    }
}

 

说明一下:

test01()是普通的工厂模式,这里有一个缺陷,就是在增加动物的时候需要更改工厂,在 public static Animal createAnimal(int type)方法中需要添加一种新类型。
test02()是优化后的测试方法,此时调用public static Animal createAnimal() throws Exception (),从配置文件中读取客户端需要的对象,此时如果需要添加动物,只需要修改配置问价就可以了,不需要再对
createAnimal()方法进行修改。

配置文件内容:

    type=com.zpj.designMode.Person
    name=所谓的高级动物
    speed=30

注意:

  注意读取配置文件的路径问题

  反射机制使用的时候类中必须有空的构造方法。