抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

设计模式-工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式分类三类:(在《设计模式》一书中将简单工厂模式与工厂方法模式合称为工厂方法模式)

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

简单工厂模式(Simple Factory)

建立一个工厂(一个函数或一个类方法)来制造新的对象。

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据自变量的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂模式

简单工厂模式优点

  • 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

简单工厂模式缺点

  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

简单工厂模式示例

定义抽象产品类

/**
 * 交通工具
 * 
 * @author jiangliuhong
 */
public abstract class Vehicle {
    public abstract void run();
}
/**
 * 汽车基础类
 * @author jiangliuhong
 */
public class Car extends Vehicle {
    private Double speed;
    private String name;

    Car(Double speed, String name) {
        this.speed = speed;
        this.name = name;
    }

    public Double getSpeed() {
        return speed;
    }

    public void setSpeed(Double speed) {
        this.speed = speed;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(getName() + " speed is :" + getSpeed());
    }
}

定义具体的汽车实现类

/**
 * 小汽车
 * @author jiangliuhong
 */
public class SedanCar extends Car {
    public SedanCar() {
        super(200D,"SedanCar");
    }
}
/**
 * 摩托车
 * @author jiangliuhong
 */
public class Motobike extends Car  {
    public Motobike() {
        super(120D, "Motobike");
    }
}

定义工厂类

/**
 * 汽车工厂类
 * @author jiangliuhong
 * @date
 */
public class CarFactory {

    public static Vehicle createCar(CarType carType) {
        switch (carType) {
            case MOTOBIKE:
                return new Motobike();
            case SEDANCAR:
                return new SedanCar();
            default:
                return null;
        }
    }

}
/**
 * 汽车类别
 * @author jiangliuhong
 */
public enum CarType {
    /** 小汽车 */
    SEDANCAR,
    /** 摩托车 */
    MOTOBIKE;
}

模拟运行

/**
 * @author jiangliuhong
 */
public class SimpleMain {
    public static void main(String[] args) {
        Vehicle v1 = CarFactory.createCar(CarType.MOTOBIKE);
        v1.run();
        Vehicle v2 = CarFactory.createCar(CarType.SEDANCAR);
        v2.run();
    }
}

控制台输出

Motobike speed is :120.0
SedanCar speed is :200.0

工厂方法模式(Factory Method)

工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method是一个类的实例化延迟到其子类。

在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

工厂方法模式

工厂方法模式优点

  • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名
  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,正是因为所有的具体工厂类都具有同一抽象父类
  • 使用工厂方法模式的另一个优点是在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”

工厂方法模式缺点

  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度

工厂方法模式示例

Factory方法

/**
 * 工厂方法接口
 * 
 * @author jiangliuhong
 */
public interface VehicleFacotry {

    /**
     * 创建交通工具
     * @return
     */
    public Vehicle createVehicle();
}

public interface CarFactory extends VehicleFacotry {

}

public class MotobikeFactory implements CarFactory {

    @Override
    public Vehicle createVehicle() {
        return new Motobike();
    }
}

public class SedanCarFactory implements CarFactory {
    @Override
    public Vehicle createVehicle() {
        return new SedanCar();
    }
}

抽象工厂模式(Abstract Factory)

抽象工厂模式提供一个创建一系列或相互依赖的对象的接口,而无需指定它们具体的类。

抽象工厂模式

抽象工厂模式优点

  • 隔离了具体类的生成,使得用户不需要知道什么被创建了。
  • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。

抽象工厂模式缺点

  • 添加新的产品对像时,难以扩展抽象工厂以便生产新种类的产品。

抽象工厂模式示例

定义ProductB

public abstract class Tv {

    public abstract void player();

}
public class LeTv extends Tv {

    @Override
    public void player() {
        System.out.println("player LeTv");
    }
}
public class ChangTv extends Tv {
    @Override
    public void player() {
        System.out.println("player ChangTv");
    }
}

定义Factory

public interface Factory {
    public Tv createTv();
    public Vehicle createVehicle();
}
public class ConOneFactory implements Factory {
    @Override
    public Tv createTv() {
        return new LeTv();
    }

    @Override
    public Vehicle createVehicle() {
        return new Motobike();
    }
}
public class ConTwoFactory implements Factory {
    @Override
    public Tv createTv() {
        return new ChangTv();
    }

    @Override
    public Vehicle createVehicle() {
        return new SedanCar();
    }
}

参考资料

http://design-patterns.readthedocs.io/zh_CN/latest/

https://www.jianshu.com/p/bf8341c75304

评论