抽象工厂模式
- 写在前面:此内容与工厂模式有关,了解过工厂模式再看这个更容易理解
一 概述
什么是抽象工厂模式
- 概念:提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类。
一眼看上去是不是每个字都认识,连起来就不懂了?没关系,下面有我的理解。
为什么使用抽象工厂模式
- 看过我前面的工厂模式或者自己对工厂模式有理解的伙伴们知道工厂模式就是通过工厂创建对象,但是一类工厂生产一类产品,但是如果出现两种或者两种以上的对象我们就需要创建许多的不同种类的工厂,即使这些产品之间有着某种联系,所以我们要对工厂这边进行改造。所以这就引出了抽象工厂。
- 给大家举个例子来说明一下,举这个例子之前先引入两个概念,产品族与产品等级,4个东西:华为手机,小米手机,华为电脑,小米电脑。其中华为手机,小米手机都是手机同属于一个产品等级,同理华为电脑,小米电脑也都属于一个产品等级,而小米手机,小米电脑都是小米公司的产品,所以他们是同一个产品族,同样的华为手机华为电脑也是同一个产品族。假设,我们要生产这么4样东西,如果用工厂模式,我们需要创建两类工厂和四个具体工厂来生产,代码很多。所以我们可以设计一个超级工厂并且通过两个具体工厂小米工厂与华为工厂来生产各自属于自己的产品。
- 说了这么多,其实在我的理解中抽象工厂与工厂模式最大的区别就是抽象工厂中的工厂方法中可以返回多种对象。而工厂模式中的工厂方法只返回一种对象,下面我们通过代码具体实现以下方便大家理解。
二 模式的结构与实现
结构
- 抽象产品:一个接口或者抽象类,负责定义具体产品必须实现的方法
- 具体产品:抽象产品的实现类或者子类,具体取决于抽象产品。
- 抽象工厂:一个接口或者抽象类,负责定义若干个抽象方法
- 具体工厂:抽象工厂的实现类或者子类,重写抽象工厂的抽象方法,返回具体产品的对象。
具体实现
按照上面的例子来实现
- 抽象产品
电脑
/*
* 抽象产品
*/
public abstract class Computer {
public abstract void start();
public abstract void use();
}
手机
/*
* 抽象产品
*/
public abstract class Phone {
public abstract void start();
public abstract void use();
}
- 具体产品
华为电脑
public class HuaWeiComputer extends Computer{
@Override
public void start() {
System.out.println("华为电脑开机");
}
@Override
public void use() {
System.out.println("使用华为电脑");
}
}
华为手机
public class HuaWeiphone extends Phone{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void use() {
System.out.println("使用华为手机");
}
}
小米电脑
public class XiaoMiComputer extends Computer{
@Override
public void start() {
System.out.println("小米电脑开机");
}
@Override
public void use() {
System.out.println("使用小米电脑");
}
}
小米手机
public class XiaoMiphone extends Phone{
@Override
public void start() {
System.out.println("小米手机开机");
}
@Override
public void use() {
System.out.println("使用小米手机");
}
}
- 抽象工厂
/*
* 抽象工厂
*/
public abstract class IFactory {
public abstract Phone createPhone();
public abstract Computer createComputer();
}
- 具体工厂
小米工厂
public class XiaoMiFactory extends IFactory{
//返回具体的小米手机
@Override
public Phone createPhone() {
return new XiaoMiphone();
}
//返回具体的小米电脑
@Override
public Computer createComputer() {
return new XiaoMiComputer();
}
}
华为工厂
public class HuaWeiFactory extends IFactory{
@Override
public Phone createPhone() {
return new HuaWeiphone();
}
@Override
public Computer createComputer() {
return new HuaWeiComputer();
}
}
- 主函数
public class MainClass {
public static void main(String[] args) {
//创建一个小米工厂
IFactory xm = new XiaoMiFactory();
//使用小米工厂生产手机
Phone xp = xm.createPhone();
xp.start();
xp.use();
//使用小米工厂生产电脑
Computer xc = xm.createComputer();
xc.start();
xc.use();
System.out.println("======================");
//创建华为工厂
IFactory hw = new HuaWeiFactory();
//使用华为工厂生产手机
Phone hp = hw.createPhone();
hp.start();
hp.use();
//使用华为工厂生产电脑
Computer hc = hw.createComputer();
hc.start();
hc.use();
}
}
- 结果
三 模式的优缺点与适用场景
优缺点
- 优点:
1.抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类解耦。
2.使用抽象工厂模式可以方便的为用户配置一系列对象,用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不同系列的对象
3.可以随时添加具体的工厂为用户提供一组相关的对象 - 缺点
抽象工厂中规定了产品集合,如果要添加新的产品族,就会很困难(需要改代码)。违反了开-闭原则。
适用场景
- 系统需要为用户提供多个对象,但不希望用户直接使用new运算符实例化这些对象,即希望用户和创建对象的类解耦
- 系统需要为用户提供多个对象,以便用户联合使用他们,但又不希望用户来决定这些对象是如何关联的。
- 系统需要为用户提供一系列对象,但只需要用户知道这些对象有哪些方法可用,不需要用户知道这些对象的创建过程
这就是我学习的抽象工厂,本文有些个人的理解,如果有错误或者大家有更好的想法可以告诉我。