其中最关键的角色是 → 抽象产品,它的好坏直接决定了抽象工厂和具体功能能否发挥最大作用,应用此模式时应该朝着 分析共性规律 的方向走,仔细分析实现类该如何实现。
以上面说的茶和小吃为例写个抽象工厂模式的例子,先是产品类:
// 抽象产品类① public abstract class Tea { protected abstract String createTea(); } // 抽象产品类② public abstract class Snack { public abstract String createSnack(); } // 具体产品类(茶类沿用之前的,小吃类新增两个) public class HandGrab extends Snack { @Override public String createSnack() { return "手抓饼"; } } public class FishBall extends Snack { @Override public String createSnack() { return "章鱼小丸子"; } }
接着是抽象工厂和测试用例:
// 抽象工厂(套餐) public abstract class SetMenuFactory { public abstract Tea createTeaMaker(); public abstract factory.Snack createSnackMaker(); } // 具体工厂① public class ASetMenuFactory extends SetMenuFactory { @Override public Tea createTeaMaker() { return new TapiocaMilkTea(); } @Override public Snack createSnackMaker() { return new HandGrab(); } } // 具体工厂② public class BSetMenuFactory extends SetMenuFactory { @Override public Tea createTeaMaker() { return new TapiocaMilkTea(); } @Override public Snack createSnackMaker() { return new FishBall(); } } // 测试用例 public class SuperTeaStoreTest { public static void main(String[] args) { SetMenuFactory factoryFirst = new ASetMenuFactory(); System.out.println("产出一杯:" + factoryFirst.createTeaMaker().createTea() + "和一份:" + factoryFirst.createSnackMaker().createSnack()); SetMenuFactory factorySecond = new BSetMenuFactory(); System.out.println("产出一杯:" + factorySecond.createTeaMaker().createTea() + "和一份:" + factorySecond.createSnackMaker().createSnack()); } }
运行结果如下:
网络异常,图片无法展示
|
抽象工厂的优点:符合开闭原则和单一原则、将使用和创建的代码解耦,增加新的产品系列容易。抽象工厂的缺点:代码量和学习成本增加,变更产品结构困难,比如上面的套餐,要添加调味包的产品。
0x2、如何设计实现一个DI框架
在讲依赖反转原则(DIP)的时候就提过这几个名词,再粘贴下以便区分:
网络异常,图片无法展示
|
工厂模式与DI容器的关系
DI容器底层最基本的设计思路就是基于工厂模式的,相当于一个大工厂,负责在程序启动时,根据配置(创建哪些类对象、对象创建需要依赖哪些其他类对象) 事先创建好对象。当程序需要用到某个类对象时,直接从容器中获取即可。正是因为它持有一堆对象,所以这个框架才被称为 "容器"。
DI容器的三个核心功能:
- ① 配置解析:通过一种形式让应用告知DI容器要创建哪些对象,一般通过配置文件形式,如Spring的配置文件;
- ② 对象创建:DI容器根据配置文件提供的信息创建对象,Java中一般通过反射来动态加载类、创建对象;
- ③ 生命周期管理:返回新对象还是复用、是否延迟加载、是否配置对象初始化/销毁的钩子等;
课程中写了一个实现简单DI容器的例子,比较简单,只列下流程:最小原型设计、提供执行入口、配置文件解析、核心工厂类设计。
Android中常见的依赖注入框架有下面几类:
- View注入:XUtils、Android Annotations、ButterKnife
- 参数注入:ARouter
- 对象注入:koin、Dagger2、Hilt
前两类严格意义上不能算真正的注入,本文内容感觉有些单薄,后面会挑一个DI框架的源码进行分析巩固