目录
1. 简单工厂模式
2. 工厂方法模式
1. 简单工厂模式
简单工厂模式(Simple Factory Patterm)又称为静态工厂方法模式(Static Factory Model),它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义了一个类来负责创建其他类的实例,被创建的实例通常都有共同的父类。
实现:
首先定义一个抽象类 Product 和继承 Product 的实体类(ProductA/productB)。实体类要实现抽象类Product 里的抽象方法 method(),在各自的 method() 方法里实现自己的功能。下一步定义工厂类 Factory。
工厂类里有一个 createProduct() 方法,根据传入的参数来判断返回的对象类型。
步骤1:创建抽象类 Product
abstract public class Product{
public abstract void print();
}
步骤2:创建继承 Product 的实体类
public class ProductA extends Product{
@override
public void print(){
System.out.println("产品A");
.....
}
}
public class ProductB extends Product{
@override
public void print(){
System.out.println("产品B");
......
}
}
步骤3:创建一个工厂,返回特定的产品对象
public class ProductFactory{
// 创建具体产品实例
public static Product createProduct(String type){
if(type == null){
return null;
}
if(type.equals("A"){
return new ProductA();
} else{
return new ProductB();
}
}
}
步骤4:使用该工厂,通过传递类型信息来获取实体类的对象
public class SimpleFactoryPattermDemo{
public static void main(String[] args){
// createProduct("A") 里传入参数A, 获取到 ProductA 对象
Product productA = ProductFactory.createProduct("A");
productA.print();
// createProduct("B") 里传入参数A, 获取到 ProductB 对象
Product productB = ProductFactory.createProduct("B"):
productB.print();
}
}
优点:对象的创建和使用是分离的。客户端无需知道创建对象的细节,也无需直接创建产品对象。
缺点: 系统扩展困难,违背了开闭原则。当我们新增一个 ProductC时,在步骤3中就会修改 createProduct 的逻辑,新增一个 if 语句来满足 ProductC 对象的创建和返回。这一点就违背了开闭原则的修改关闭。
2. 工厂方法模式
由于简单工厂模式不符合开闭原则,因此引入了工厂方法模式,也称为工厂模式,它完全符合开闭原则。
工厂方法模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于类创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
实现:
步骤1:创建一个Coffee 接口
public interface Coffee{
void createCoffee();
}
步骤2:创建实现 Coffee 接口的实体类
public class AmericanCoffee implements Coffee{
@override
public void createCoffee(){
System.out.println("create AmericanCoffee");
....
}
}
public class LatteCoffee implements Coffee{
@override
public void createCoffee(){
System.out.println("create LatteCoffee");
....
}
}
步骤3:创建一个 Factory 接口
public interface CoffeeFactory{
Coffee createCoffeeInstance();
}
步骤4:创建实现 CoffeeFactory 接口的实体类,分别对应步骤2中 的 Coffee 实体类
public class AmericanCoffeeFactory implements CoffeeFactory{
@override
public Coffee createCoffeeInstance(){
System.out.println("return a AmericanCoffee`s instance");
return new AmericanCoffee();
}
}
public class LatteCoffeeFactory implements CoffeeFactory{
@override
public Coffee createCoffeeInstance(){
System.out.println("return a LatteCoffee`s instance");
return new LatteCoffee();
}
}
步骤5:使用 CoffeeFactory 来获取 Coffee 实例
public class FactoryPatternDemo{
public static void main(Stirng[] args){
// TODO 写法1
// 通过配置文件的方式来判断具体是哪一种 Coffee, 然后使用对应的CoffeeFactory
CoffeeFactory coffeeFactory = new CoffeeFactory();
Coffee coffee = coffeeFactory.createCoffeeInstance();
coffee.createCoffee();
}
}
当我们需要新增加一个 BlackCoffee 时,只需要新建类 BlackCoffee implements Coffee 和 BlackCoffeeFactory implements CoffeeFactory 就 ok了,满足了开闭原则中的扩展开发,修改关闭。
优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程; 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则
注意:复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。