目录
1 简单工厂模式
1.1 组成
1.2 简单例子
1.2.1 抽象产品角色
1.2.2 具体产品角色
1.2.3 工厂类角色
1.2.4 顾客测试类
1.3 优缺点
1.3.1 优点
1.3.2 缺点
2 抽象工厂模式
2.1 模式的定义与特点
2.2 模式的结构与实现
2.2.1 模式的结构
2.2.2 案例实现
前面说到有三种工厂模式:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
简单工模式时类的创建模式,又叫做静态工厂方法(static Factory Method)。简单工厂模式是一个工厂对象决定创建出哪一种产品类的实例。它存在的目的很简单:定义一个创建对象的接口。
- 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
- 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
- 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
以汽车和汽车工厂为例
package simpleFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public interface car {
void name();
}
package simpleFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class tesla implements car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
package simpleFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class wuLing implements car{
@Override
public void name() {
System.out.println("五菱");
}
}
package simpleFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class carFactory {
public static car getCar(String car){
if (car.equals("wuLing")){
return new wuLing();
}
else if (car.equals("tesla")){
return new tesla();
}
else {
return null;
}
}
}
package simpleFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class consumer {
public static void main(String[] args) {
car wuLing = carFactory.getCar("wuLing");
car tesla = carFactory.getCar("tesla");
wuLing.name();
tesla.name();
}
}
结果
专门定义一个工厂类负责创建其他类的实例,最大的优点在于工厂类中包含了必要的逻辑,根据客户需要的条件动态实例化相关的类。
当需要增加一种产品时,比如ProductC就需要修改简单工厂类SimpleFactory(增加if-else块),这违背了开闭原则。
注意
尽管违背了开闭原则,但是在实际中,相对工厂方式模式,我们还是用简单工厂模式更多
前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
同种类称为同等级,也就是说:工厂方法模式中只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
使用抽象工厂模式一般要满足以下条件。
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
缺点
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。
抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
抽象工厂模式的结构图
华为和小米两种厂商生产的手机和路由器
抽象产品
手机产品接口
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public interface iphoneProduct {
void start();
void shutdown();
void callup();
void cendSSMS();
}
路由器产品接口
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public interface irouterProduct {
void start();
void shutdown();
void openWIFI();
void setting();
}
具体产品
小米手机
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class xiaoMiPhone implements iphoneProduct{
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void shutdown() {
System.out.println("小米手机关机");
}
@Override
public void callup() {
System.out.println("小米手机打电话");
}
@Override
public void cendSSMS() {
System.out.println("小米手机发短信");
}
}
小米路由器
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class xiaoMiRouter implements irouterProduct{
@Override
public void start() {
System.out.println("打开小米路由器");
}
@Override
public void shutdown() {
System.out.println("关闭小米路由器");
}
@Override
public void openWIFI() {
System.out.println("打开小米WIFI");
}
@Override
public void setting() {
System.out.println("小米路由器设置");
}
}
华为手机
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class huaWeiPhone implements iphoneProduct{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void shutdown() {
System.out.println("华为手机关机");
}
@Override
public void callup() {
System.out.println("华为手机打电话");
}
@Override
public void cendSSMS() {
System.out.println("华为手机发短信");
}
}
华为路由器
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class huaWeiRouter implements irouterProduct{
@Override
public void start() {
System.out.println("打开华为路由器");
}
@Override
public void shutdown() {
System.out.println("关闭华为路由器");
}
@Override
public void openWIFI() {
System.out.println("打开华为WIFI");
}
@Override
public void setting() {
System.out.println("华为路由器设置");
}
}
抽象工厂
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public interface ProductFactory {
iphoneProduct phone();
irouterProduct router();
}
具体工厂
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class xiaoMiFactory implements ProductFactory{
@Override
public iphoneProduct phone() {
return new xiaoMiPhone();
}
@Override
public irouterProduct router() {
return new xiaoMiRouter();
}
}
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class HuaWeiFactory implements ProductFactory{
@Override
public iphoneProduct phone() {
return new huaWeiPhone();
}
@Override
public irouterProduct router() {
return new huaWeiRouter();
}
}
客户测试类
package abstractFactory;
/**
* @author Mr.Qing
* @date 2021/11/8
*/
public class Client {
public static void main(String[] args) {
xiaoMiFactory xiaoMiFactory = new xiaoMiFactory();
iphoneProduct phone = xiaoMiFactory.phone();
phone.callup();
phone.cendSSMS();
irouterProduct router = xiaoMiFactory.router();
router.openWIFI();
System.out.println("===============");
HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
iphoneProduct phone1 = huaWeiFactory.phone();
phone1.cendSSMS();
irouterProduct router1 = huaWeiFactory.router();
router1.openWIFI();
}
}
结果
个人理解:抽象工厂,就是抽象的抽象