目录
1.抽象工厂模式定义
2.优点
3.缺点
7.应用场景
8.本质
9.涉及的设计原则
10.相关设计模式
11.开源框架中应用
抽象工厂模式定义:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
重点是接口之间的相关性:
优点:
-
产品一致性:抽象工厂模式确保创建的产品对象之间具有一致性,因为它们都是由同一个工厂创建的。
-
封装性:客户端代码与具体产品类解耦,因为它们只与抽象产品和抽象工厂接口交互,不需要了解具体的实现细节。
-
扩展性:可以轻松添加新的产品家族,只需创建新的具体工厂类即可,不需要修改现有的客户端代码。
缺点:
-
复杂性增加:引入了多个工厂类和多个产品家族,增加了系统的复杂性。
-
不容易添加新的产品家族:如果需要添加新的产品家族,需要修改抽象工厂接口及其所有的具体工厂类,可能影响到现有的系统。
抽象工厂模式结构说明:
-
抽象工厂接口(Abstract Factory):定义了一组抽象方法,每个方法用于创建一个相关的产品对象。通常,每个具体工厂类都实现了这个接口,以创建特定的产品家族。
-
具体工厂类(Concrete Factory):具体工厂类是抽象工厂接口的具体实现,负责创建一组相关的产品对象。
-
抽象产品接口(Abstract Product):定义了产品对象的通用接口,包括产品的属性和行为。
-
具体产品类(Concrete Product):具体产品类是抽象产品接口的具体实现,实现了抽象产品接口中定义的属性和行为。
工作流程:
-
客户端需要使用一组相关的产品对象,但不关心具体的产品类。
-
客户端通过与抽象工厂接口和抽象产品接口交互来请求产品。
-
具体工厂类实现了抽象工厂接口,负责创建一组相关的产品对象。
-
具体工厂类根据客户端的请求创建并返回相应的具体产品对象。
-
客户端使用返回的产品对象进行操作,而无需了解其具体实现。
示例:
定义一个抽象产品类Door,它包含一个抽象方法show() ,表示产品的展示:
// 抽象产品类
public abstract class Door {
public abstract void show();
}
定义具体产品类WoodDoor和IronDoor,它们继承自抽象产品类Door,并实现了抽象方法show() :
public class WoodDoor extends Door {
@Override
public void show() {
System.out.println("我是木门...");
}
}
// 具体的产品类 - 铁门
public class IronDoor extends Door {
@Override
public void show() {
System.out.println("我是铁门...");
}
}
定义一个抽象产品类Expert,它包含一个抽象方法hello() ,表示工匠打招呼:
// 抽象产品类
public abstract class Expert {
public abstract void hello();
}
定义具体产品类WoodExpert和IronExpert,它们继承自抽象产品类Expert,并实现了抽象方法hello() :
// 具体的产品类 - 木匠
public class WoodExpert extends Expert {
@Override
public void hello() {
System.out.println("我是木匠...");
}
}
// 具体的产品类 - 铁匠
public class IronExpert extends Expert {
@Override
public void hello() {
System.out.println("我是铁匠...");
}
}
定义一个抽象工厂类Creator,它包含createDoor()和createExpert() ,表示创建产品和创建专家。
// 抽象工厂类
public abstract class Creator {
public abstract Door createDoor();
public abstract Expert createExpert();
}
定义具体工厂类WoodFactory和IronFactory,它们继承自抽象工厂类Creator,并实现了抽象方法createDoor()和createExpert() :
// 具体的工厂类 - 木材工厂
public class WoodFactory extends Creator {
@Override
public Door createDoor() {
return new WoodDoor();
}
@Override
public Expert createExpert() {
return new WoodExpert();
}
}
// 具体的工厂类 - 钢铁工厂
public class IronFactory extends Creator {
@Override
public Door createDoor() {
return new IronDoor();
}
@Override
public Expert createExpert() {
return new IronExpert();
}
}
最后是客户端代码,通过对应工厂类创建具体的相关联产品对象:
public class AbstractFactoryClient {
public static void main(String[] args) {
// 木材工厂的木工师傅装木门
Creator creator = new WoodFactory();
Door door = creator.createDoor();
Expert expert = creator.createExpert();
door.show();
expert.hello();
// 钢铁工厂的铁匠师傅装铁门
creator = new IronFactory();
door = creator.createDoor();
expert = creator.createExpert();
door.show();
expert.hello();
}
}
应用场景:
-
当需要创建一组相关或依赖的对象,而不仅仅是一个对象时,可以使用抽象工厂模式。这个对象家族通常具有一定的关联性。
-
当希望通过工厂类来集中管理和维护对象的创建,方便后续的修改和扩展,以及确保产品的一致性。
-
当需要遵循开闭原则,支持系统的可扩展性,以便能够引入新的产品家族而不影响已有代码。
本质:
抽象工厂模式的本质是将对象的创建过程延迟到子类中,以支持创建一组相关的对象,同时提供了一种方式来保证这组对象的一致性。
涉及的设计原则:
-
开闭原则(Open/Closed Principle):通过添加新的具体工厂类和产品类,可以扩展工厂模式的功能,而不需要修改现有的客户端代码,符合开闭原则。
-
依赖倒置原则(Dependency Inversion Principle):工厂方法模式通过抽象工厂接口和抽象产品接口,实现了高层模块(客户端)不依赖于底层模块(具体产品),符合依赖倒置原则。
相关设计模式:
-
工厂方法模式(Factory Method Pattern):
- 相关性:工厂方法模式是抽象工厂模式的一个特例,它将对象的创建延迟到子类中,用于创建一组相关的对象。
- 应用:在很多情况下,抽象工厂模式可以通过工厂方法模式来实现。例如,抽象工厂模式用于创建多个产品家族,而工厂方法模式用于创建单个产品。
-
建造者模式(Builder Pattern):
- 相关性:建造者模式用于创建复杂对象,通常将对象的构建过程分解成多个步骤。抽象工厂模式通常与建造者模式一起使用,用于构建复杂对象的部分。
- 应用:在某些情况下,抽象工厂模式可以用于创建建造者所需的一组相关对象。
-
单例模式(Singleton Pattern):
- 相关性:抽象工厂模式可以用于创建单例对象,以确保在整个应用程序中只有一个实例。
- 应用:虽然不是主要应用场景,但抽象工厂模式可以用于创建单例对象的工厂类。
-
适配器模式(Adapter Pattern):
- 相关性:适配器模式用于将一个接口转换为另一个接口,以便不同的类可以协同工作。抽象工厂模式可以用于创建适配器的不同实现。
- 应用:在一些框架和库中,抽象工厂模式可用于创建适配器,以满足不同的接口需求。
开源框架中应用:
-
java标准库:Java标准库中的Swing GUI库使用抽象工厂模式来创建不同操作系统下的用户界面组件。不同的LookAndFeel工厂用于创建特定风格的界面组件。
-
Hibernate ORM框架:Hibernate使用抽象工厂模式来创建数据库连接,不同的数据库提供商有不同的连接工厂实现。
-
Java数据库连接池:一些Java数据库连接池,如Apache DBCP(数据库连接池),使用抽象工厂模式来创建不同数据库连接的工厂类。
-
图形库:一些图形库使用抽象工厂模式来创建不同平台的图形渲染器和图形操作对象,以便跨平台开发。
这些示例中,抽象工厂模式用于创建不同家族的相关对象,从而实现了高内聚、低耦合的设计,同时提供了灵活性,使框架更易于扩展和维护。