设计模式-工厂模式


简单工厂

定义

简单工厂模式(Simple Factory Pattern)因为内部使用静态方法根据不同参数构造不同产品对象实例,也称静态工厂方法模式。
在简单工厂模式中,可以根据参数的不同返回不同实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单地说,一个工厂类 XxxFactory,里面有一个静态方法,根据我们不同的参数,返回不同的派生自同一个父类(或实现同一接口)的实例对象

demo

public class SimpleFactoryPattern {
    public static void main(String[] args) {
        Animal animal = AnimalFactory.createAnimal("0");
        animal.name();

        animal = AnimalFactory.createAnimal("1");
        animal.name();
    }
}

interface Animal {
    void name();
}

class Dog implements Animal {

    @Override
    public void name() {
        System.out.println("I'm dog.");
    }
}

class Cat implements Animal {
    @Override
    public void name() {
        System.out.println("I'm cat.");
    }
}

class AnimalFactory {

    public static Animal createAnimal(String type) {
        if ("0".equals(type)) {
            return new Dog();
        } else if ("1".equals(type)) {
            return new Cat();
        }
        return null;
    }
}

优点

1)实现起来非常简单,也充分利用了多态机制
2)解耦(使调用端不再创建对象,而是交给工厂去创建),并且对内部实现屏蔽(调用端不知道具体实现)

缺点

违反开闭原则(对扩展开放,对修改关闭),如果有一个新的对象要添加,那么就要修改工厂

工厂方法

定义

定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。

demo

public class Demo {

    public static void main(String[] args) {
        AnimalFactory animalFactory = new DogFactory();
        Animal animal = animalFactory.createAnimal();
        animal.name();

        animalFactory = new CatFactory();
        animal = animalFactory.createAnimal();
        animal.name();
    }
}


interface Animal {
    void name();
}

class Dog implements Animal {

    @Override
    public void name() {
        System.out.println("I'Demo dog.");
    }
}

class Cat implements Animal {
    @Override
    public void name() {
        System.out.println("I'Demo cat.");
    }
}

interface AnimalFactory {
    Animal createAnimal();
}

class DogFactory implements AnimalFactory{

    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}

class CatFactory implements AnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}

优点

1)用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
2)在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点

1)每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

适用场景

1)当一个类不知道它所需要创建的对象的类的时候
2)当一个类希望又它的子类来指定它创建的对象的时候
3)当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候

案例

Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口,他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean

BeanFactory接口包含了getBean方法

Object getBean(String name):返回Sprin容器中id为name的Bean实例。

调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。即Bean实例的创建过程完全透明。
在使用BeanFactory接口时,一般都是使用这个实现类:org.springframework.beans.factory.xml.XmlBeanFactory。然而ApplicationContext作为BeanFactory的子接口,使用它作为Spring容器会更加方便。它的实现类有:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。

抽象工厂

定义

提供了一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

public class Demo {
    public static void main(String[] args) {
        AnimalFactory animalFactory = new SparrowFactory();

        Species species = animalFactory.createSpecies();
        species.name();

        LifeStyle lifeStyle = animalFactory.createLifeStyle();
        lifeStyle.style();

    }
}


// 生活方式
interface LifeStyle {
    void style();
}

// 水里生活
class Water implements LifeStyle {


    @Override
    public void style() {
        System.out.println("生活在水里");
    }
}

// 陆地生活
class Terrestrial implements LifeStyle {
    @Override
    public void style() {
        System.out.println("陆地生活");
    }
}

// 物种
interface Species {
    void name();
}

class Bird implements Species {
    @Override
    public void name() {
        System.out.println("我是鸟类!");
    }
}

class Fish implements Species {
    @Override
    public void name() {
        System.out.println("我是鱼类!");
    }
}

// 动物工厂
interface AnimalFactory {
    LifeStyle createLifeStyle();

    Species createSpecies();
}

// 麻雀
class SparrowFactory implements AnimalFactory{

    @Override
    public LifeStyle createLifeStyle() {
        return new Terrestrial();
    }

    @Override
    public Species createSpecies() {
        return new Bird();
    }
}

// 鲤鱼
class CarpFactory implements AnimalFactory{
    @Override
    public LifeStyle createLifeStyle() {
        return new Water();
    }

    @Override
    public Species createSpecies() {
        return new Fish();
    }
}

优点:

1)具备和工厂方法模式一样的优点
2)当增加一个新的产品族时不需要修改原代码,满足开闭原则
3)可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。

缺点

1)难以支持新种类的产品,支持新种类的产品需要拓展工厂接口,这将涉及抽象工厂及其所有子类的

适用场景

1)当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
2)系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
3)系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

案例

声明:微默网|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 设计模式-工厂模式


不以物喜,不以己悲! 不忘初心,方得始终!