1、概述
- 在面向对象编程中,创建对象实例最常用的方式就是通过 new 操作符构造一个对象实例,但在某些情况下,new 操作符直接生成对象会存在一些问题。举例来说,对象的创建需要一系列的步骤:可能需要计算或取得对象的初始位置、选择生成哪个子对象实例、或在生成之前必须先生成一些辅助对象。 在这些情况,新对象的建立就是一个 “过程”,而不仅仅是一个操作,就像一部大机器中的一个齿轮传动。
- 针对上面这种情况,我们如何轻松方便地构造对象实例,而不必关心构造对象示例的细节和复杂过程?解决方案就是使用一个工厂类来创建对象。
工厂模式有三种方式
简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。
通过专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。
2-1、基本使用
抽象产品类:Fruit.java
- 具体产品类:Apple.java、Banana.java ```java public interface Fruit { void eat(); }
public class Apple implements Fruit{ @Override public void eat() { System.out.println(“吃苹果”); } }
public class Banana implements Fruit{ @Override public void eat() { System.out.println(“吃香蕉”); } }
- FruitFactory.java
```java
public class FruitFactory {
public static Fruit createFruit(String name){
if ("apple".equals(name)){
return new Apple();
}else if ("banana".equals(name)){
return new Banana();
}
return null;
}
}
测试代码
public class Main {
public static void main(String[] args) {
Fruit apple = FruitFactory.createFruit("apple");
apple.eat();
Fruit banana = FruitFactory.createFruit("banana");
banana.eat();
}
}
2-2、进阶用法
反射实例类
public class FruitFactory {
public static Fruit createFruit(String name) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class fruit = Class.forName(name);
return (Fruit) fruit.newInstance();
}
}
验证
public class Main {
public static void main(String[] args) {
try {
Fruit apple = FruitFactory.createFruit("com.company.factory.Apple");
apple.eat();
Fruit banana = FruitFactory.createFruit("com.company.factory.Banana");
banana.eat();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
2-3、优缺点
简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
3、工厂方法模式
3-1、四个角色
抽象工厂角色:1个,工厂方法模式的核心,创建产品的类必须实现该接口
- 具体工厂角色:多个,该角色实现了抽象工厂接口,具体如何创建产品就是在该类中实现
- 抽象产品角色:1个,所有产品的超类,负责实现产品共性的抽象定义
具体产品角色:多个,该角色实现了抽象产品接口,负责具体不同产品的业务逻辑
3-2、代码示例
抽象工厂、具体工厂 ```java public interface FruitFactory {
Fruit createFruit(); }
public class BananaFactory implements FruitFactory{
@Override
public Fruit createFruit() {
return new Banana();
}
}
public class AppleFactory implements FruitFactory{ @Override public Fruit createFruit() { return new Apple(); } }
- 使用
```java
public class Main {
public static void main(String[] args) {
Fruit apple = new AppleFactory().createFruit();
apple.eat();
Fruit banana = new BananaFactory().createFruit();
banana.eat();
}
}
3-3、优缺点
- 工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。
但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
4、抽象工厂模式
4-1、代码示例
多个抽象产品类+多个具体抽象产品类 ``` //发动机以及型号
public interface Engine {}
public class EngineA implements Engine{
public EngineA(){
System.out.println(“制造—>EngineA”);
}
}
public class EngineB implements Engine{
public EngineB(){
System.out.println(“制造—>EngineB”);
}
}
//空调以及型号
public interface Aircondition {}
public class AirconditionA implements Aircondition{
public AirconditionA(){
System.out.println(“制造—>AirconditionA”);
}
}
public class AirconditionB implements Aircondition{
public AirconditionB(){
System.out.println(“制造—>AirconditionB”);
}
}
- 一个抽象工厂类+多个具体抽象工厂类
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
```
4-2、工厂方法模式 VS 抽象工厂模式
- 工厂方法模式只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。
- 抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例