设计模式---简单工厂模式

设计模式—简单工厂模式

本人这段时间在学习设计模式,视野和深度有限,若有写的不准确的,恳请各位客官轰炸和指导!
我们为什么需要工厂模式呢?工厂模式能够带给我们什么好处呢?本人将在后续的博客里会给予说明。在这里只讨论简单工厂模式的集中写法及每种写法的特点:
首先,写一个接口:

package com;

public interface Person {
    /**
     * 说话
     */
    public void speak();
}

在写两个具体产品类(这里是男人和女人)

package com;
//男人
public class Man implements Person {
    @Override
    public void speak() {
        System.out.println("I am a man!");
    }
}

package com;
//女人
public class Woman implements Person {
    @Override
    public void speak() {
        System.out.println("I am a woman!");
    }
}

简单工厂模式中的工厂类
工厂类1:

package com;
//工厂类1
public class PersonFactory {
    /**
     * 获得一个男人实例
     * @return
     */
    public static Person getMan(){
        return new Man();
    }
    /**
     * 获得一个女人实例
     * @return
     */
    public static Person getWoman(){
        return new Woman();
    }
}

测试类 1:

package com;
//测试类1
public class PersonTest {
    public static void main(String[] args) {
        //通过工厂方法获得一个男人
        Person man=PersonFactory.getMan();
        //通过工厂方法获得一个女人
        Person woman=PersonFactory.getWoman();
        man.speak();
        woman.speak();
    }
}

分析
工厂类1是简单工厂类的一种写法,这中写法最大的问题是扩展性不好,为什么呢?假设,你想要通过该工厂类得到小孩这个实例的话,你就必须在工厂类里重新添加一个方法类得到小孩的实例,这样不利于扩展了。当你同一类型不同产品增多的话,就要在工厂类里添加相应的方法类的到相应产品的实例,这既不利于扩展也不利于维护,所以下面是一种改进
工厂类2:

package com;
//工厂类2
public class PersonFactory {
    /**
     * 通过判断来获取相应的实例
     * @param name
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public static Person getPerson(String name) 
            throws InstantiationException, IllegalAccessException{
        if(name.equalsIgnoreCase("man")){
            return Man.class.newInstance();
        }else if(name.equalsIgnoreCase("woman")){
            return Woman.class.newInstance();
        }else{
            System.out.println("找不到相应的类");
            return null;
        }
    }
}

测试类2:

package com;
//测试类2
public class PersonTest {
    public static void main(String[] args) 
            throws InstantiationException, IllegalAccessException {
        //通过工厂方法(传递参数)获得一个男人
        Person man=PersonFactory.getPerson("man");
        //通过工厂方法(传递参数)获得一个女人
        Person woman=PersonFactory.getPerson("woman");
        man.speak();
        woman.speak();
    }
}

分析:
工厂类2中方法getPerson(String name)通过参数来判断应该创建哪个实例。工厂类1里每增加一类对象就要在在该类里增加一个相应的方法来获得相应的实例,而在工厂类2里是通过增加判断语句来创建相应的实例的,看起来工厂类2并没有太多的减少工厂类1的工作量,那就看下面一个例子:
工厂类3:

package com;
//工厂类3
public class PersonFactory {
    /**
     * @param name
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException 
     */
    public static Person getPerson(String name) 
            throws  ClassNotFoundException, InstantiationException, IllegalAccessException{
        Class person=Class.forName(name);
        return (Person) person.newInstance();
    }
}

测试类3:

package com;
//测试类3
public class PersonTest {
    public static void main(String[] args) 
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        //通过工厂方法获得一个男人
        Person man=PersonFactory.getPerson("com.Man");
        //通过工厂方法获得一个女人
        Person woman=PersonFactory.getPerson("com.Woman");
        man.speak();
        woman.speak();
    }
}

分析
现在看,工厂类3就比工厂类2和工厂类1扩展型就强多了,不管你要得到个多少种不同的对象,你都可以不用修改工厂类了,只要在具体创建对象的代码里创建对象即可了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脑机接口社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值