Java设计模式之---工厂模式介绍

工厂模式介绍

工厂模式是一种常见的创建型设计模式,它提供了一种创建对象的最佳实践,将对象的创建过程封装到一个单独的类中,从而将对象的使用代码与具体对象的实现代码解耦。

在Java中,工厂模式可以分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。

  1. 简单工厂模式:简单工厂模式是最基本的工厂模式,它定义了一个工厂类,根据客户端的需求创建不同的产品对象。
  2. 工厂方法模式:工厂方法模式通过定义一个工厂接口和多个具体的工厂实现类,实现了客户端与具体产品类的解耦。
  3. 抽象工厂模式:抽象工厂模式是一种针对产品族的创建模式,它通过定义一个抽象工厂接口和多个具体工厂实现类,实现了客户端与具体产品族的解耦。

简单工厂模式

通常由以下三个角色组成:

  1. 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
  2. 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
  3. 工厂类:负责创建具体产品的实例,它通常包含一个静态的工厂方法,根据传入的参数不同返回不同的具体产品实例。

下面是一个简单工厂模式的示例代码:

// 抽象产品类
interface Product { void show();
}
// 具体产品类A
class ProductA implements Product { @Override
    public void show() { System.out.println("ProductA");
    }
}
// 具体产品类B
class ProductB implements Product { @Override
    public void show() { System.out.println("ProductB");
    }
}
// 工厂类
class Factory { public static Product createProduct(String type) { Product product = null;
        if ("A".equals(type)) { product = new ProductA();
        } else if ("B".equals(type)) { product = new ProductB();
        }
        return product;
    }
}
// 客户端代码
public class Client { public static void main(String[] args) { Product productA = Factory.createProduct("A");
        productA.show(); // ProductA
        Product productB = Factory.createProduct("B");
        productB.show(); // ProductB
    }
}

在这个例子中,抽象产品类 Product 定义了产品的共性,具体产品类 ProductA 和 ProductB 分别实现了 Product 接口,并实现了自己的产品特性。工厂类 Factory 负责创建具体产品的实例,根据传入的参数不同返回不同的具体产品实例。最后,客户端通过调用工厂类的静态方法来获取所需的产品对象。

优点:在于它将对象的创建过程封装在工厂类中,客户端只需要调用工厂类的方法即可获取所需的对象,从而简化了客户端代码的编写。

缺点:在于当需要添加新的产品时,需要修改工厂类的代码,增加了工厂类的复杂度和维护成本。

工厂方法模式

Java工厂模式中的工厂方法模式是一种更为灵活的工厂模式,它将对象的创建过程延迟到子类中进行,从而让客户端代码与具体产品类的实现解耦。

工厂方法模式通常由以下四个角色组成:

  1. 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
  2. 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
  3. 抽象工厂类:定义工厂方法的接口,用于返回一个具体产品的实例。
  4. 具体工厂类:实现抽象工厂类定义的工厂方法,返回具体产品的实例。

下面是一个工厂方法模式的示例代码:

// 抽象产品类
interface Product { void show();
}
// 具体产品类A
class ProductA implements Product { @Override
    public void show() { System.out.println("ProductA");
    }
}
// 具体产品类B
class ProductB implements Product { @Override
    public void show() { System.out.println("ProductB");
    }
}
// 抽象工厂类
interface Factory { Product createProduct();
}
// 具体工厂类A
class FactoryA implements Factory { @Override
    public Product createProduct() { return new ProductA();
    }
}
// 具体工厂类B
class FactoryB implements Factory { @Override
    public Product createProduct() { return new ProductB();
    }
}
// 客户端代码
public class Client { public static void main(String[] args) { Factory factoryA = new FactoryA();
        Product productA = factoryA.createProduct();
        productA.show(); // ProductA
        Factory factoryB = new FactoryB();
        Product productB = factoryB.createProduct();
        productB.show(); // ProductB
    }
}

在这个例子中,抽象产品类 Product 定义了产品的共性,具体产品类 ProductAProductB 分别实现了 Product 接口,并实现了自己的产品特性。抽象工厂类 Factory 定义了工厂方法的接口,用于返回一个具体产品的实例。具体工厂类 FactoryAFactoryB 实现了 Factory 接口的工厂方法,分别返回 ProductAProductB 的实例。客户端通过创建具体工厂类的实例来获取所需的产品对象。

优点:在于它将对象的创建过程延迟到具体工厂类中进行,客户端代码只需要和抽象工厂类和抽象产品类打交道,不需要知道具体的产品类是哪个,从而提高了代码的灵活性和可扩展性。

缺点:在于它需要定义抽象工厂类和具体工厂类,增加了类的数量和复杂度。

抽象工厂模式

Java工厂模式中的抽象工厂方法模式是一种更为高级的工厂模式,它通过引入抽象工厂类和抽象产品类的概念,使得工厂可以生产多种不同类型的产品,而不仅仅是一个产品。这种模式通常被用于一组相关或相互依赖的产品族的创建。

抽象工厂方法模式通常由以下四个角色组成:

  1. 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
  2. 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
  3. 抽象工厂类:定义了一个工厂方法接口,用于返回一组相关或相互依赖的产品。
  4. 具体工厂类:实现抽象工厂类定义的工厂方法,返回一组相关或相互依赖的产品。

下面是一个抽象工厂方法模式的示例代码:

// 抽象产品类
interface Button { void paint();
}
// 具体产品类A
class WinButton implements Button { @Override
    public void paint() { System.out.println("WinButton");
    }
}
// 具体产品类B
class MacButton implements Button { @Override
    public void paint() { System.out.println("MacButton");
    }
}
// 抽象产品类
interface TextField { void paint();
}
// 具体产品类A
class WinTextField implements TextField { @Override
    public void paint() { System.out.println("WinTextField");
    }
}
// 具体产品类B
class MacTextField implements TextField { @Override
    public void paint() { System.out.println("MacTextField");
    }
}
// 抽象工厂类
interface GUIFactory { Button createButton();
    TextField createTextField();
}
// 具体工厂类A
class WinGUIFactory implements GUIFactory { @Override
    public Button createButton() { return new WinButton();
    }
    @Override
    public TextField createTextField() { return new WinTextField();
    }
}
// 具体工厂类B
class MacGUIFactory implements GUIFactory { @Override
    public Button createButton() { return new MacButton();
    }
    @Override
    public TextField createTextField() { return new MacTextField();
    }
}
// 客户端代码
public class Client { public static void main(String[] args) { GUIFactory factory = new WinGUIFactory();
        Button button = factory.createButton();
        TextField textField = factory.createTextField();
        button.paint(); // WinButton
        textField.paint(); // WinTextField
        factory = new MacGUIFactory();
        button = factory.createButton();
        textField = factory.createTextField();
        button.paint(); // MacButton
        textField.paint(); // MacTextField
    }
}

优点:

  1. 客户端代码与具体产品的实现分离,使得客户端代码更容易扩展和维护;
  2. 提供了一种可以切换产品族的方式,只需要切换具体工厂类即可;
  3. 遵循开闭原则,新增产品族时只需要增加具体工厂和具体产品类即可,不需要修改原有代码;
  4. 封装了产品的创建过程,对客户端隐藏了具体产品的实现细节。

缺点:

  1. 抽象工厂模式增加了系统的抽象性和理解难度,需要理解抽象工厂和具体工厂之间的关系,以及抽象产品和具体产品之间的关系;
  2. 增加了系统的复杂度和代码量,需要定义大量的接口和抽象类;
  3. 不容易支持新种类的产品,需要修改抽象工厂接口和所有具体工厂类。

总的来说,抽象工厂方法模式适用于需要创建一系列相关或依赖对象的产品族,并且这些产品族的实现是相对稳定的,不容易扩展新的产品种类,但需要支持新增的产品族。

工厂模式的优点在于它可以降低代码的耦合度,提高代码的可维护性和可扩展性。它还可以隐藏对象创建的细节,使得客户端不需要知道对象的创建过程,只需要通过工厂类获取对象即可。然而,工厂模式也存在一些缺点,比如增加了代码的复杂度和维护成本。