工厂模式的作用-----一些个人的理解(1)

省掉工厂也是可以实现多态以解耦。
下面的例子是参考别人的博客,连接放在最下面了。

eg:

package factory;

public interface Leifeng {
    void sweep();
    void wash();
    void buyRice();
}

//实现类
package factory;

public class Student implements Leifeng {
    private String name;
    public Student(String name){
        this.name = name;
    }

    @Override
    public void sweep() {
        System.out.println(name+"扫地(大学生)");
    }

    @Override
    public void wash() {
        System.out.println(name+"洗菜");
    }

    @Override
    public void buyRice() {
        System.out.println(name+"买米");
    }
}



package factory;

public class Volunteer implements Leifeng {
    private String name;
    public Volunteer(String name){
        this.name = name;
    }

    @Override
    public void sweep() {
        System.out.println(name+"扫地(志愿者)");
    }

    @Override
    public void wash() {
        System.out.println(name+"洗菜");
    }

    @Override
    public void buyRice() {
        System.out.println(name+"买米");
    }
}

//工厂
package factory;

public interface IFactory {
    Leifeng createLeiFeng(String name);
}

//工厂实现类
package factory;

public class StudentFactory implements IFactory {
    @Override
    public Student createLeiFeng(String name) {
        return new Student(name);
    }
}

package factory;

public class VolunteerFactory implements IFactory {
    @Override
    public Leifeng createLeiFeng(String name) {
        return new Volunteer(name);
    }
}

//测试类

package factory;

public class Test {
    public static void main(String[] args) {
        IFactory factory = new StudentFactory();
        Leifeng l = factory.createLeiFeng("张三");
        IFactory factory1 = new VolunteerFactory();
        Leifeng ll = factory1.createLeiFeng("李四");
        l.sweep();
        ll.sweep();
    }
}

这样可以实现增添新的Leifeng实现类不需要更改已有的生产类,只要新增对应的工厂即可。

但是为什么要增加工厂类的实现呢?

直接在测试类里创建你想要类的不可以吗?答案是可以的,你可以直接在测试类中创建student类或者volunteer类。

这个例子确实是可以直接这么做的,从而达到和工厂方法实现一样的效果,而且代码量更少。

工厂模式的特点在于其把类型的“定义过程”和"实例化过程"分离开,也就是在类自身的构造器之外,附加一个经常被误认为没有什么卵用的”工厂类“。当一个类有多种实现类的时候,我们需要使用工厂类来隔离实例化过程。

class ServiceFactory{
    Service getService(){
        if(a)
            Service sA = new ServiceA();
        if(b)
			Service sB = new ServiceB();
    }
}

但是这好像依旧不是使用这个设计模式的根本原因,如果用户输入了生成service的条件,为何不在主类里面直接使用if条件判断并生成呢?为何还要创建一个工厂?这是要把这部分功能给抽取出来,我的理解是实现单一原则,每个类执行一个特定的功能,这样来实现去耦合。为何要把功能单一分割出来?这是要降低风险,保证安全。例如你把两个功能模块写在一个类里,这样的话,如果其实一个功能出现问题,你在修改bug的同时,意味着你可以得到另一个功能的源码,并且你可以更改。这样带来一些风险,所以要创建工厂将创建服务的功能抽取出来,这样创建服务这地方如果需要新增服务,只需要给你工厂类的实现就可以了。上例是简单工厂实现,简单工厂的缺点是当你每次新增服务时都需要修改ServiceFactory,工厂方法实现,则是将servicefactory抽象为一个接口,然后为每一种服务都创建一个实现该接口工厂,这样新增服务时就不需要修改ServiceFactory这个类,而是新增工厂类了。(如果只有一个工厂,不同的service在不同环境下有不同的实现,如果环境很多,则实现很多,而且每种实现可能是不同组的人实现的,如果都写在一个类内,则变量可能冲突,而且别的组的人修改他们的实现改变一些变量,可能影响我们自己的实现,所以才有了工厂方法模式,这样每组人只需要修改他们自己实现的工厂类即可。)

而且在《Think in Java》中,作者提出”组合优先于继承“(好处参考状态模式),利用多态,状态模式可以在runtime改变内部组件的类型,从而改变类的行为,更加灵活。

而且这是其一,其二是更根本的原因。

在这里,service并没有给出具体实现,所以看不出工厂太大的作用,只会让人感觉代码量增多了,好处不明显。但是如果service很复杂呢?现在我们脱离开service那个例子,假设我们现在要创建一个机器,这个机器很复杂,由很多组件组装而成,如果我们把这些都写在一个类里,那么这个机器类的内容就是各个组件成员变量,机器的行为,以及在构造器中定义机器的组装流程。如果这个机器很复杂,那么构造方法就会特别复杂,而且由于单一原则,机器应该只负责怎么使用,而不用管机器是怎怎么产生的,所以,我们把构造器单独提取出来,即把机器的创建流程提取出来,从而形成了工厂类。实现了机器构建与机器的去耦。

除以上两点,还有第三点。

如果student和volunteer类或者service占用资源特别多呢?你还可以在一上来就直接创建吗?那么你可能会说我们在需要他们的时候再创建不就好了,反正使用工厂类也是在需要的时候再去创建的,那我们在需要使用这些service类的时候直接创建service不就好了? 那我再问,如果service服务需要在多个地方使用呢?或者需要很多实例化对象分布在不同的位置,比如需要创建十个服务分布在程序的各个位置,那样如果需要修改服务,你怎么办呢? 把这十处找出来挨个修改吗?(因为很多服务创建的时候需要很多参数,如果有一个参数需要修改,那么你就要把所有创建实例的地方都找出来挨个修改),这时候你如果提前把所有要用到的实例都创建好,则回到了第一个问题,如果这些类占用资源很多,就会造成资源浪费。所以结合原因2,工厂类的好处我想已经不言而喻了吧。可以在工厂类中把创建服务所需要的参数准备好,然后当需要修改的时候,只需要修改工厂类对应的参数值,而其他的地方的创建语句等等,完全不需要修改。而且工厂类仅仅只是定义了一些创建服务所需要的参数,占用资源很少,所以可以提前创建。而且工厂类实现了1对多,1个工厂类可以生产无数该类服务。适应service创建不固定的情形。所以,这就是为什么需要工厂模式。
以上全为个人理解,如果有错误或者理解不当的地方,请大佬们指正。
参考博文:https://www.zhihu.com/question/30351872

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值