工厂模式

48 阅读4分钟

工厂模式

  1. 工厂模式属于“创建型模式”,用来封装和管理类的创建,终极目的是为了解耦,实现创建者和调用者的分离。

  2. 工厂模式可以细分为三种:

    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

传统代码模式:

public class TraditionalCode {
    public static void main(String[] args) {
        Product product = getOrder("A");
        product.print();
    }
​
    public Product TraditionalCode(String type) {
        Product product = null;
        if (type.equals("A")) {
            product = new ProductA();
        }else if (type.equals("B")) {
            product = new ProductB();
        }
        return product;
    }
}
​
//抽象产品
abstract class Product{
    public abstract void print();
}
//具体产品
class ProductA extends Product{
    @Override
    public void print() {
        System.out.println("产品A");
    }
}
//具体产品
class ProductB extends Product{
    @Override
    public void print() {
        System.out.println("产品B");
    }
}
  1. Factroy要解决的问题是:希望能够创建一个对象,但创建过程比较复杂,希望对外隐藏这些细节。

  2. 如何理解过程比较复杂?

    • 对象代码的作者希望隐藏对象真实的的类型,而构造函数一定要真实的类名才能用。
    • 对象创建时会有很多参数来决定如何创建出这个对象。比如你有一个数据写在文件里,可能是xml也可能是json。
    • 创建对象可能是一个pool里的,不是每次都凭空创建一个新的。而pool的大小等参数可以用另外的逻辑去控制。
    • 创建一个对象有复杂的依赖关系,比如Foo对象的创建依赖A,A又依赖B,B又依赖C……。于是创建过程是一组对象的的创建和注入。手写太麻烦了。所以要把创建过程本身做很好地维护。
    • 避免在构造函数中抛出异常。
    • 等等.....

简单工厂模式

简单工厂模式(Simple Factory),又称为静态工厂方法模式(Static Factory Method),可以根据参数的不同返回不同的类的实例。简单工厂模式专门定义了一个类来创建其他类的实例,被创建的实例通常具有共同的父类。

package 设计模式.工厂模式.简单工厂模式;
​
//工厂
public class SimpleFactory{ 
​
    public static void main(String[] args) {
        Product product = Factory.creatProduct("A");
        product.print();
    }
}
​
class Factory{
    public static Product creatProduct (String type) {
        if (type.equals("A")) {
            return new ProductA();
        }else if (type.equals("B")) {
            return new ProductB();
        }
        return null;
    }
}
​
//抽象产品
abstract class Product{
    public abstract void print();
}
//具体产品
class ProductA extends Product{
    @Override
    public void print() {
        System.out.println("产品A");
    }
}
//具体产品
class ProductB extends Product{
    @Override
    public void print() {
        System.out.println("产品B");
    }
}

UML类图:

image-20230131154648169

结构:

  1. 工厂(SimpleFactory)
  2. 抽象的产品(Product)
  3. 具体的产品(ProductA、ProductB)

优点:对象的创建和使用分离,客户端无需关心对象创建的细节 缺点:违反OCP原则

工厂方法模式

目标:解决简单工厂违反开闭原则的问题

package 设计模式.工厂模式.工厂方法模式;
​
//客户端
public class FactoryMethod {
    public static void main(String[] args) {
        Product product = new ProductAFactory().creatProduct();
        product.print();
    }
}
​
// 抽象工厂
interface Factory {
    public Product creatProduct();
}
// 具体工厂
class ProductAFactory implements Factory{
    @Override
    public Product creatProduct() {
        System.out.println("ProductAFactory");
        return new ProductA();
    }
}
// 具体工厂
class ProductBFactory implements Factory{
    @Override
    public Product creatProduct() {
        System.out.println("ProductBFactory");
        return new ProductB();
    }
}
// 抽象产品
abstract class Product {
    public abstract void print();
}
​
// 具体产品
class ProductA extends Product {
    @Override
    public void print() {
        System.out.println("产品A");
    }
}
​
// 具体产品
class ProductB extends Product {
    @Override
    public void print() {
        System.out.println("产品B");
    }
}

UML类图:

image-20230131161327403

image-20230131211453399

结构:

  1. 抽象工厂(SimpleFactory)
  2. 具体工厂(ProductAFactory、ProductBFactory)
  3. 抽象的产品(Product)
  4. 具体的产品(ProductA、ProductB)

优缺:

  1. 简单工厂模式的优点得到了保留
  2. 灵活性更强,新增产品只需要新增一个工厂类即可,满足开闭原则

缺点:

  1. 类的个数变多了,增加了复杂性
  2. 每个工厂只能生产一种产品

抽象工厂模式

抽象工厂(AbstractFactory)模式定义:是一种为访问类提供一个创建一组相关或相互依赖的对象的接口,且访问类无需指定所要产品的具体类就能得到同族的不同等级的产品的结构模式。比如:牧场既养动物又能种植物、电器厂既生产电视又生产空调

image-20230131164105608

package 设计模式.工厂模式.抽象工厂模式;
​
public class AbstractFactory {
    public static void main(String[] args) {
        Factory factory = new ProductAFactory();
        Phone phone = factory.creatPhone();
        phone.print();
    }
}
​
// 抽象工厂
interface Factory {
    public Phone creatPhone();
    public Mask creatMask();
}
// 具体工厂
class ProductAFactory implements Factory{
    @Override
    public Phone creatPhone() {
        System.out.println("ProductAFactory - creatPhone");
        return new IPhone();
    }
​
    @Override
    public Mask creatMask() {
        System.out.println("ProductAFactory - creatMask");
        return new N95();
    }
}
// 具体工厂
class ProductBFactory implements Factory{
​
    @Override
    public Phone creatPhone() {
        System.out.println("ProductBFactory - creatPhone");
        return new HuaWeiPhone();
    }
​
    @Override
    public Mask creatMask() {
        System.out.println("ProductBFactory - creatMask");
        return new KN90();
    }
    
}
// 抽象产品
abstract class Phone {
    public abstract void print();
}
​
// 具体产品
class IPhone extends Phone {
    @Override
    public void print() {
        System.out.println("产品:iPhone");
    }
}
​
// 具体产品
class HuaWeiPhone extends Phone {
    @Override
    public void print() {
        System.out.println("产品:华为手机");
    }
}
​
// 抽象产品
abstract class Mask {
    public abstract void print();
}
​
// 具体产品
class N95 extends Mask {
    @Override
    public void print() {
        System.out.println("产品:N95");
    }
}
​
// 具体产品
class KN90 extends Mask {
    @Override
    public void print() {
        System.out.println("产品:KN90");
    }
}
​

image-20230131163449913

优点:

  1. 支持了一个工厂生产多种产品的诉求
  2. 增加产品族满足开闭原则

缺点:

  1. 同一个工厂内新增产品线不满足开闭原则

参考文档

  1. blog.csdn.net/weixin_4375…
  2. www.zhihu.com/question/42…
  3. blog.csdn.net/weixin_3387…
  4. www.jianshu.com/p/f0c38abaa…
  5. zhuanlan.zhihu.com/p/42629760
  6. rikka-2.gitbook.io/effective_k…