工厂方法模式与抽象工厂

2018-02-07  本文已影响0人  柚子过来

作用:定义一个创建对象的接口,并提供工厂方法将类的实例化推迟到子类,由子类决定要实例化的类是哪一个。

OO原则:

封装变化
针对接口编程优于针对实现编程
依赖抽象,不要依赖具体类



Example:
1、定义一个Flower接口,所有类型的flower都实现自该接口,可以保证类型一致:

public interface Flower {
}

public class ShangHaiFlower implements Flower {
}

public class BeiJingFlower implements Flower {
}

2、定义一个工厂接口,并在里面定义工厂方法以及其他方法:

 public abstract class FlowerStore {
public void dealFlower() {
    Flower flower;
    flower = createFlower();
    //do something with the flower;
}

   public abstract Flower createFlower();   //创建Flower的工厂方法,工厂方法是抽象的,它依赖子类来处理对象的创建。
}

3、第二步就将创建的行为推迟至子类,我们可以定义多个不同的FlowerStore子类:

public class BeiJingFlowerStore extends FlowerStore {
@Override
public Flower createFlower() {
    return new BeiJingFlower();
}
}

public class ShangHaiFlowerStore extends FlowerStore {

@Override
public Flower createFlower() {
    return new ShangHaiFlower();
}
}

4、这样我们就可以获取自己想要的Flower了:

public class Main {

public static void main(String[] args) {
    FlowerStore flowerStore = new ShangHaiFlowerStore();
    Flower flower = flowerStore.createFlower();

    FlowerStore flowerStore1 = new BeiJingFlowerStore();
    Flower flower1 = flowerStore1.createFlower();
}
}

代码写的比较简单,可能会觉得没什么用,为什么不直接new BeiJingFlowerStore和ShangHaiFlowerStore呢。FlowerStore是一个抽象工厂,它的子类new BeiJingFlowerStore和ShangHaiFlowerStore才是具体的工厂。FlowerStore并不知道会创建什么样的Flower,它只知道它花创建出来并做一些其他的处理就行了。这样的好处在于如果子类变了,比如BeiJingFlowerStore的功能需要修改或者需要其他类型的FlowerStore的时候,我们只需要再加一个定义就行了,而且FlowerStore中还可以定义所有子类型共有的方法如dealFlower,这样将减少代码重复。当然,在实际中可能比较常见的是只有一个具体工厂,但是顶层设计一个抽象工厂还是很有必要的。

另外试想一下如果代码里写的是:

BeiJingFlower flower = new BeiJingFlower();

那么如果后期我不想用BeiJingFlower了呢?我想使用BeiJingFlower1.0怎么办?那就要修改所有代码了。额,怎么感觉说成了多态的好处...哦,不对,这里的重点是工厂方法呀,工厂方法可以根据子类自己的需求创建对象。

可能又有疑问说那这样行不行:

Flower flower = new BeiJingFlower(); 

嗯,上面这个就是多态,确实解决了想要BeiJingFlower1.0的问题,但是这不是重点啊,工厂模式的重点是要把创建对象的逻辑封装起来,不要在代码里直接用new,而是调用工厂方法来创建。

比如子类中可能有很多需求玫瑰、百合等等等等,这些实例化的逻辑如果直接写在代码里,那以后要加其他花,要修改已有的花就都要修改代码,但是把这些变化封装起来和代码隔离开就便于后期维护了:

public class BeiJingFlowerStore extends FlowerStore {
@Override
public Flower createFlower(String type) {
    if(type.equals("rose")) {
        return new BeiJingRoseFlower();
    }else if(type.equals("lily")) {
        return new BeiJingLilyFlower();
    }else {
        ... ...
    }
}
}

所以要注意:
1、实例化的代码以后可能会变化,所以封装起来最好
2、要面向接口编程,new一个对象是面向实现的

so,一个工厂方法模式涉及的属性有:抽象工厂类、具体工厂类、抽象产品类、具体产品类。
注意!说的是工厂方法模式,和抽象工厂模式是两回事,虽然它们都属于工厂模式,那下面说一下抽象工厂又是什么:
使用工厂方法可以发现,利用它创建对象时需要扩展一个类并覆盖它的工厂方法。这就是工厂方法,而抽象工厂顾名思义是一个工厂,它和前面写的FlowerStore很像,其实它一般就是使用工厂方法来实现具体工厂,它定义多个方法来创建产品集合。

工厂方法:将实例化的代码解耦或者不确定实例化哪些类
抽象工厂:创建产品家族或者想让相关的产品集合起来

上一篇 下一篇

猜你喜欢

热点阅读