文章参考:23种设计模式
工厂模式分为:简单工厂模式(静态工厂方法模式)、工厂方法模式、抽象工厂模式
简单工厂模式
简单工厂模式有一个具体工厂类,没有抽象工厂类,可以生产多个产品。
简单工厂模式不在 GoF 23 种设计模式之列。
角色:
- 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
- 具体产品(ConcreteProduct):是简单工厂模式的创建目标。
实现:
//抽像产品
public interface Product {
public void say();
}
//具体产品1
public class ProductImpl1 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl1 !!!!!");
}
}
//具体产品2
public class ProductImpl2 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl2 !!!!!");
}
}
//简单工厂类
public class SimpleFactory {
//创建实例的方法通常为静态(static)方法
public static Product getProduct(int i){
switch (i){
case 1:
return new ProductImpl1();
case 2:
return new ProductImpl1();
}
return null;
}
}
public class Main {
public static void main(String[] args) {
Product product = SimpleFactory.getProduct(1);
product.say();
}
}
思考:简单工厂模式如果新增一种产品应该怎么办?
除了新增一种产品实现类,还需要修改简单工厂中获取实例的方法,不满足开闭原则。
工厂方法模式
工厂方法模式对简单工厂模式进一步抽象化,满足开闭原则。
角色:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
可以看出角色中比简单工厂模式增加了“抽象工厂”。
实现:
public interface Product {
public void say();
}
//具体产品1
public class ProductImpl1 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl1 !!!!!");
}
}
//具体产品2
public class ProductImpl2 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl2 !!!!!");
}
}
//抽象工厂
public interface AbstractFactory {
public Product newProduct();
}
//具体工厂1
public class Factory1 implements AbstractFactory{
@Override
public Product newProduct() {
System.out.println("I am Factory 1 !!!!");
return new ProductImpl1();
}
}
//具体工厂2
public class Factory2 implements AbstractFactory{
@Override
public Product newProduct() {
System.out.println("I am Factory 2 !!!!");
return new ProductImpl2();
}
}
public class Main {
public static void main(String[] args) {
AbstractFactory factory = new Factory1();
Product product = factory.newProduct();
product.say();
}
}
思考:
工厂方法模式如果新增一个产品,需要新增一个产品实现类、一个工厂实现类,不用对原来的工厂类做修改,所以满足了开闭原则。
虽然工厂方法模式相比简单工厂模式满足了开闭原则,但是一个工厂就只能生产一种产品,简单工厂模式可以生产多个产品的。
抽象工厂模式
怎么解决工厂方法模式中一个工厂只能生产一种产品的问题呢?那就一个工厂生产多种产品呗!
角色:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
可以看出抽象工厂模式和工厂方法模式的角色是一样的,不同点在于抽象工厂模式有多个抽象产品,工厂中也对应有多个创建产品的方法。
实现:
//第一种抽象产品
public interface Product {
public void say();
}
//第一种具体产品1
public class ProductImpl1 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl1 !!!!!");
}
}
//第一种具体产品2
public class ProductImpl2 implements Product{
@Override
public void say() {
System.out.println("I am ProductImpl2 !!!!!");
}
}
//抽象工厂
public interface AbstractFactory {
public Product getProduct();
public NewProduct getNewProduct();
}
//具体工厂1
public class Factory1 implements AbstractFactory{
@Override
public Product getProduct() {
return new ProductImpl1();
}
@Override
public NewProduct getNewProduct() {
return new NewProductImpl1();
}
}
//具体工厂2
public class Factory2 implements AbstractFactory{
@Override
public Product getProduct() {
return new ProductImpl2();
}
@Override
public NewProduct getNewProduct() {
return new NewProductImpl2();
}
}
public class Main {
public static void main(String[] args) {
AbstractFactory factory = new Factory1();
Product product = factory.getProduct();
NewProduct newProduct = factory.getNewProduct();
product.say();
newProduct.say();
}
}
思考:
增加一种已有种类的产品(已定义的抽象产品的实现),需要新增一个工厂实现类(新的产品由新的工厂生产),这种情况下不会改动原有的工厂类,符合开闭原则;
但是新增一种新的产品类型(未定义的抽象产品),则所有的工厂类都要新增一个新产品的生产方法,就不符合开闭原则了。
总结
简单工厂模式中,只有一个工厂类,工厂类不是抽象的,新增产品需要修改原来的工厂类的方法,所以不满足开闭原则;
工厂方法模式解决了上述问题,将工厂类进行抽象,每个工厂只生产一种产品,新增产品类不需要修改原来的工厂类,满足了开闭原则;
抽象工厂模式让一个工厂生产了两种产品,虽然生产的产品多了,但是新增产品类型时,是不满足开闭原则的。
具体用哪一种模式,要根据实际情况做出选择。