工厂模式的主要作用:实现了创建者和调用者的分离。

工厂模式的核心本质:实例化对象,用工厂方法代替new操作;将选择实现类、创建对象统一管理和控制。从而将调用者和我们的实现类进行解耦。

详细可以分为:

       简单工厂模式:用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改原来的代码)

       工厂方法模式:用来生产同一等级结构中的固定产品。(支持增加任意产品,不需要修改已有代码)

       抽象工厂模式:用来生产不同产品族的全部产品。(对于增加新的产品无能为力,支持增加产品族)

面向对象设计的基本原则:

1 OCP 开闭原则(Open Closed Principle):一个软件的实体应该对扩展开放,对修改关闭;

2 DIP 依赖倒转原则(Dependence Inversion Principle):要针对接口编程,不要针对实现编程;

3 LoD 迪米特法则(Law of Demeter):只与你直接的朋友通信,避免和陌生人通信。

 

1、简单工厂模式

1.1 创建接口

package com.zdw.factory.simpleFactory;

public interface Car {
    void run();
}

1.2 创建两个实现类

1.2.1 奥迪车

package com.zdw.factory.simpleFactory;

public class Audi implements Car {
    @Override
    public void run() {
        System.out.println("我是一辆奥迪车,我百公里加速8秒");
    }
}

1.2.2 吉利车

package com.zdw.factory.simpleFactory;

public class JiLi implements Car {
    @Override
    public void run() {
        System.out.println("我是一辆吉利车,我百公里加速10秒");
    }
}

1.3 创建工厂类

通过工厂类来创建不同的实现类对象:

package com.zdw.factory.simpleFactory;

/**
 * 简单工厂类,通过参数来创建不同的实现对象
 */
public class CarFactory {
    public static Car createCar(String type){
        if("奥迪".equals(type)){
            return new Audi();
        }else if("吉利".equals(type)){
            return new JiLi();
        }else {
            return null;
        }
    }
}

1.4 测试

package com.zdw.factory.simpleFactory;

public class TestSimpleFactory {
    public static void main(String[] args) {
        Car audi = CarFactory.createCar("奥迪");
        Car jiLi = CarFactory.createCar("吉利");
        audi.run();
        jiLi.run();
    }
}

1.5 要点

1、简单工厂模式也叫静态工厂模式,因为一般工厂类的方法都是静态方法,通过类名直接调用;

2、对于增加新产品,就必须要修改已有代码。

2、工厂方法模式

简单工厂模式不能完全满足OCP开闭原则,而工厂方法模式可以解决这个问题;

工厂方法模式和简单工厂模式最大的不同在于:简单工厂模式只有一个工厂类(对于一个小项目或一个模块而言),而工厂方法模式有一组实现了相同接口的工厂类。

2.1 创建接口和实现类

我们创建的Car接口及其两个实现类Audi和JiLi是跟上面的简单工厂模式的是一样的代码,这里不再赘述。

2.2 创建工厂接口和工厂实现

2.2.1 创建工厂接口

工厂接口中有一个方法,方法的作用是用来创建Car对象;

package com.zdw.factory.factoryMethod;

/**
 * 工厂方法的接口
 */
public interface CarFactory {
    Car createCar();
}

2.2.2 创建工厂实现类

奥迪车的工厂类

package com.zdw.factory.factoryMethod;

public class AudiFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Audi();
    }
}

吉利车的工厂类

package com.zdw.factory.factoryMethod;

public class JiLiFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new JiLi();
    }
}

2.3 测试

package com.zdw.factory.factoryMethod;

public class TestFactoryMethod {
    public static void main(String[] args) {
        Car audi = new AudiFactory().createCar();
        Car jiLi = new JiLiFactory().createCar();
        audi.run();
        jiLi.run();
    }
}

现在如果我们需要新增一个产品奔驰车,那么我们不需要修改之前的代码,只要新增一个BenChi类实现Car接口,通过新增一个BenChiFactory实现CarFactory工厂接口。这样就满足了OCP开闭原则了。但是它会新增很多的类,会变得复杂,所以其实项目中简单工厂模式是用的比较多的。

3、抽象工厂模式

抽象工厂模式用来生产不同产品族的全部产品。对于增加新的产品,无能为力,但是支持新增新的产品族。

抽象工厂模式是工厂方法模式的升级版,在有多个业务品种,业务分类时,通过抽象工厂生产需要的对象是一种非常好的解决方式。

下面我们还是以Car作为例子,假设Car是由三个主要的部件组成的:发动机,轮胎和座椅。不同等级的部件可以生产出不同的Car。

3.1 创建发动机及其实现

package com.zdw.factory.abstractFactory;

public interface Engine {
    void run();
}

//高端发动机
class LuxuryEngine implements Engine{

    @Override
    public void run() {
        System.out.println("高端发动机,转速快,噪声小");
    }
}

//低端发动机
class LowEngine implements Engine{

    @Override
    public void run() {
        System.out.println("低端发动机,转速慢,噪声好大好大。。。");
    }
}

3.2 创建轮胎接口及其实现

package com.zdw.factory.abstractFactory;

public interface Tyre {
    void revolve();
}

//高端轮胎
class LuxuryTyre implements Tyre{

    @Override
    public void revolve() {
        System.out.println("高端轮胎,耐磨");
    }
}

//低端轮胎
class LowTyre implements Tyre{

    @Override
    public void revolve() {
        System.out.println("低端轮胎,不经磨,经常破。。。");
    }
}

3.3 创建座椅接口及其实现

package com.zdw.factory.abstractFactory;

public interface Seat {
    void massage();
}

class LuxurySeat implements Seat{

    @Override
    public void massage() {
        System.out.println("高端座椅可以自动按摩的,很舒服");
    }
}

class LowSeat implements Seat{

    @Override
    public void massage() {
        System.out.println("低端座椅不能按摩,坐久了屁股痛。。。。");
    }
}

3.4 创建生产Car的工厂接口及其实现

3.4.1 Car工厂接口

package com.zdw.factory.abstractFactory;

/**
 * 生产车子的工厂接口
 */
public interface CarFactory {
    Engine createEngine();
    Tyre createTyre();
    Seat createSeat();
}

3.4.2 高端车子的工厂类

package com.zdw.factory.abstractFactory;

public class LuxuryCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        return new LuxuryEngine();//生产高端发动机
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();//生产高端轮胎
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat();//生产高端座椅
    }
}

3.4.3 低端车子的工厂类

package com.zdw.factory.abstractFactory;

public class LowCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        return new LowEngine();//生产低端发动机
    }

    @Override
    public Tyre createTyre() {
        return new LowTyre();//生产低端轮胎
    }

    @Override
    public Seat createSeat() {
        return new LowSeat();//生产低端座椅
    }
}

 

3.5 测试

package com.zdw.factory.abstractFactory;

public class TestAbstractFactory {
    public static void main(String[] args) {
        CarFactory carFactory = new LuxuryCarFactory();
        Engine engine = carFactory.createEngine();
        Tyre tyre = carFactory.createTyre();
        Seat seat = carFactory.createSeat();
        engine.run();
        tyre.revolve();
        seat.massage();
    }
}

这样我们通过不能的工厂实现类,就能创建不同的车子了。

 

3.6 抽象工厂的应用场景

JDK中的Calendar的getInstance方法;

JDBC中的Connection对象的获取;

Hibernate中的SessionFactory创建Session;

Spring的IoC容器创建的管理的Bean对象;

反射Class对象的newInstance方法。

更多推荐

GOF23(2)之工厂模式(创建型模式)