设计模式之工厂模式

169 阅读5分钟

什么是工厂模式

工厂模式是一种创建型设计模式, 在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型(继承、多态)。 工厂模式划分为三类:简单工厂(静态工厂)模式、工厂方法模式、抽象工厂模式,在GoF的《设计模式: 可复用面向对象软件的基础》将简单工厂模式划分为工厂方法模式。 一句话表示:任何可以产生对象的方法或类,都可以称之为工厂。

简单工厂模式

简单工厂模式.png

什么是简单工厂模式

简单工厂模式又被称为静态工厂模式(Static Factory Method),属于创建型模式,但是不属于23种设计模式,在GoF的《设计模式: 可复用面向对象软件的基础》将简单工厂模式划分为工厂方法模式,简单工厂模式简单来说就是由工厂根据传入的参数,决定创建什么样的实例,客户端不需要关注创建逻辑。

简单工厂模式使用场景

适用于创建对象较少且客户端不关心创建逻辑的情况。

简单工厂模式优缺点

简单工厂模式优点

无需知道具体的创建细节只需传入对应参数便能获取所需要的对象,实现简单。

简单工厂模式缺点

违背了开闭原则(Open Closed Principle, OCP),如增加产品对应的需要修改工厂类,且产品越多工厂就会越复杂。

简单工厂模式实现

/**
 * 简单工厂模式
 */
public class SimpleFactory {
    /**
     * 创建对象
     * @param transportType 交通工具类型
     * @return 实例对象
     */
    public static Transport createTransport(String transportType) {
        if ("car".equalsIgnoreCase(transportType)) {
            return new Car();
        } else if ("train".equalsIgnoreCase(transportType)) {
            return new Train();
        }
        throw new IllegalArgumentException("transportType is not supported:" + transportType);
    }

    public static void main(String[] args) {
        //创建火车
        Transport transport = SimpleFactory.createTransport("train");
        transport.run();
    }
}

/**
 * 交通工具抽象类
 */
abstract class Transport{
    /**
     * 抽象方法
     */
    abstract void run();
}

/**
 * 火车
 */
class Train extends Transport{

    @Override
    void run() {
        System.out.println("火车出行 呜呜呜......");
    }
}

/**
 * 汽车
 */
class Car extends Transport{

    @Override
    void run() {
        System.out.println("汽车出行 嘀嘀嘀......");
    }
}

工厂方法模式

工厂方法.png

什么是工厂方法模式

工厂方法模式(Factory Method),属于创建型模式,与简单工厂负责创建所有产品不同,工厂方法模式将生成具体产品的任务下发到具体的产品工厂。

工厂方法模式使用场景

对象的创建逻辑比较复杂,不只是简单的new一下就可以,而是要组合其他类对象,做各种初始化操作的时候,推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。

工厂方法模式优缺点

工厂方法模式优点

  1. 避免了创建者和具体产品之间的紧密耦合。
  2. 符合单一职责原则,代码更容易维护。
  3. 符合开闭原则,方便引入新的产品类型而不去改变原有产品。

工厂方法模式缺点

  1. 类的数量增多,每增加一个产品需要增加一个产品的实现及工厂实现。
  2. 需要引入更多的子类,代码变得复杂。

工厂方法模式实现

/**
 * 工厂方法
 */
public class FactoryMethod {
    public static void main(String[] args) {
        AbstractFactory factory = new TrainFactory();
        Transport transport = factory.createTransport();
        transport.run();
    }
}

/**
 * 交通工具抽象类
 */
abstract class Transport{
    /**
     * 抽象方法
     */
    abstract void run();
}

/**
 * 工厂
 */
abstract class AbstractFactory{
    /**
     * 创建交通工具
     * @return 交通工具
     */
    abstract Transport createTransport();
}

/**
 * 汽车工厂
 */
class CarFactory extends AbstractFactory{

    @Override
    Transport createTransport() {
        return new Car();
    }
}

/**
 * 火车工厂
 */
class TrainFactory extends AbstractFactory{

    @Override
    Transport createTransport() {
        return new Train();
    }
}

/**
 * 火车
 */
class Train extends Transport {

    @Override
    void run() {
        System.out.println("火车出行 呜呜呜......");
    }
}

/**
 * 汽车
 */
class Car extends Transport {

    @Override
    void run() {
        System.out.println("汽车出行 嘀嘀嘀......");
    }
}

抽象工厂模式

抽象工厂.png

什么是抽象工厂模式

抽象工厂(Abstract Factory),属于创建型模式,是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式使用场景

系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。 需要创建的对象是一系列相互关联或相互依赖的产品族时。 系统中有多个产品族,但每次只使用其中的某一族产品。 需要与多个不同系列的相关产品交互,或者出于对扩展性的考虑。

抽象工厂模式优缺点

抽象工厂模式优点

具体产品在应用层代码隔离,无须关心创建细节,将一个系列的产品族统一管理。 避免客户端与具体产品的耦合。

抽象工厂模式缺点

产品族中扩展新的产品困难,需要修改抽象工厂的接口,增加了复杂度及维护成本。 需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。

抽象工厂模式实现


/**
 * 抽象工厂
 */
public class AbstractFactory {
    public static void main(String[] args) {
        AbstractBaseFactory factory  = new TrainFactory();
        Way build = factory.build();
        Transport transport = factory.createTransport();
        build.build();
        transport.run();
    }
}

/**
 * 交通工具抽象类
 */
abstract class Transport{
    /**
     * 抽象方法
     */
    abstract void run();
}

/**
 * 道路
 */
abstract class Way{
    /**
     * 修建
     */
    abstract void build();
}

/**
 * 工厂
 */
abstract class AbstractBaseFactory{
    /**
     * 创建交通工具
     * @return 交通工具
     */
    abstract Transport createTransport();
    /**
     * 修路
     */
    abstract Way build();


}

/**
 * 汽车工厂
 */
class CarFactory extends AbstractBaseFactory {

    @Override
    Transport createTransport() {
        return new Car();
    }

    @Override
    Way build() {
        return new Street();
    }
}

/**
 * 火车工厂
 */
class TrainFactory extends AbstractBaseFactory {

    @Override
    Transport createTransport() {
        return new Train();
    }

    @Override
    Way build() {
        return new Railway();
    }
}

/**
 * 火车
 */
class Train extends Transport {

    @Override
    void run() {
        System.out.println("火车出行 呜呜呜......");
    }
}

/**
 * 铁路
 */
class Railway extends Way{

    @Override
    void build() {
        System.out.println("修建铁路 喀喀喀......");
    }
}
/**
 * 马路
 */
class Street extends Way{

    @Override
    void build() {
        System.out.println("修建马路 轱辘......");
    }
}

/**
 * 汽车
 */
class Car extends Transport {

    @Override
    void run() {
        System.out.println("汽车出行 嘀嘀嘀......");
    }
}

总结

当创建对象逻辑比较复杂且客户但不关系具体创建细节时,可以考虑使用工厂模式,将对象的创建和使用相分离。 工厂方法是模板方法模式的一种特殊形式,工厂方法可以作为一个大型模板方法中的一个步骤。 抽象工厂可以使用单例来实现。