工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式。今天我们将学习简单工厂模式。如题,简单工厂模式将是工厂模式中最简单的。
简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static FactoryMethod)模式,它属于类创建型模式。
简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
简单工厂模式包含以下几个角色:
①Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象。
②Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
③ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。
在使用简单工厂模式时,首先需要对产品类进行重构,典型的抽象产品类代码如下:
/**
* 简单工厂模式,抽象出产品类
*/
public abstract class Product {
//所有产品类的公共业务方法
public void commonMethod() {
//公共方法的实现
}
//声明抽象业务方法
public abstract void methodDiff();
}
具体产品实现抽象类代码如下:
/**
* 子类继承抽象类,根据自身业务逻辑实现抽象方法
*/
public class ConcreteProduct extends Product {
//实现业务方法
@Override
public void methodDiff() {
}
}
简单工厂模式的核心是工厂类,在没有工厂类之前,客户端一般会使用new关键字来直接创建产品对象,而在引入工厂类之后,客户端可以通过工厂类来创建产品,代码如下:
/**
* 简单工厂模式核心为工厂类,根据不同类型,产生不同产品。
*/
public class Factory {
public static Product createProduct(String type) {
Product product = null;
if ("A".equals(type)) {
product = new ConcreteProduct();
} else {
product = new ChildProduct();
}
return product;
}
}
客户端代码如下:
public class Client {
public static void main(String[] args) {
Product product;
product = Factory.createProduct("A"); //通过工厂类创建产品对象
product.commonMethod();
product.methodDiff();
}
}
如上,在实际的应用开发中,我们可以根据具体需求去创建我们锁需要的对象,但是在这一过程中,我们会发现还是违反了java面向对象设计原则的"开闭原则",因为,当我们有新的产品类型加入时,还是要修改客户端的代码,此时我们可以将产品配置写在配置文件中,这样就对我们的代码进行了优化。
简单工厂模式总结:
优点:
(1) 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。
(2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。
(3) 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点:
(1) 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
(2) 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
(3) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统扩展和维护。
(4) 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
适用场景:
(1) 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
(2) 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。