《Android源码设计模式解析与实战》读书笔记(六)——抽象工厂模式
来源:互联网 发布:linux线程挂起与唤醒 编辑:程序博客网 时间:2024/06/10 06:31
一不小心都看了十种设计模式了,准备好好整理下,才发现还有个抽象工厂模式是被之前搁置下来的,是时候理解真正的抽象工厂模式了。
第六章 创建型设计模式——抽象工厂模式
抽象工厂模式起源于以前对不同操作系统的图形化解决方案,如不同的操作系统中的按钮和文本框其实现不同,展现效果也不一样,对每一个操作系统而言,其本身就可以构成一个产品类,而按钮和文本框控件又是其下属的产品类。
1.定义
为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类。
2.使用场景
1).一个对象族有相同的约束时可以使用抽象工厂模式。
这句话听起来很抽象,所以我们需要先理解一下产品族和产品等级的概念。
产品族是指位于不同产品等级结构中,功能却相关联的产品组成的家族。如宝马的刹车、引擎和轮胎组成一个家族,奔驰的刹车、引擎和轮胎又组成一个家族,但是这两个家族却包含了不同的产品等级,刹车、引擎和轮胎。
通过一张图说明一下:
所以每一个工厂创建出来的,不是工厂方法那样的一个产品,而是一族产品。这也就是它们俩最大的区别。
3.对比
将三种工厂方法的UML类图对比一下。
1).简单工厂模式:
2).工厂方法模式:
3).抽象工厂模式:
4.简单实现
从上面的图可以看出抽象工厂也分四大类:
抽象工厂类:工厂方法模式的核心。具体工厂角色的父类或实现的接口。
具体工厂类:含有具体业务逻辑,继承抽象工厂类或实现抽象工厂接口。
抽象产品类:具体产品的父类或实现的接口。
具体产品类:工厂类所创建的对象。
根据上面的图,来通过代码展现一下。
先创建三个产品等级的抽象产品:
public interface Brake { void brake();}
public interface Engine { void engine();}
public interface Tire { void tire();}
抽象工厂:
public abstract class CarFactory { public abstract Brake createBrake(); public abstract Engine createEngine(); public abstract Tire createTire();}
然后根据三个产品等级分别创建三个产品族的具体产品:
Audi产品族:
public class AudiBrake implements Brake { @Override public void brake() { System.out.println("Audi Brake"); }}
public class AudiEngine implements Engine { @Override public void engine() { System.out.println("Audi Engine"); }}
public class AudiTire implements Tire { @Override public void tire() { System.out.println("Audi Tire"); }}
public class BenzBrake implements Brake { @Override public void brake() { System.out.println("Benz Brake"); }}
public class BenzEngine implements Engine { @Override public void engine() { System.out.println("Benz Engine"); }}
public class BenzTire implements Tire { @Override public void tire() { System.out.println("Benz Tire"); }}
BMW产品族:
public class BMWBrake implements Brake { @Override public void brake() { System.out.println("BMW Brake"); }}
public class BMWEngine implements Engine { @Override public void engine() { System.out.println("BMW Engine"); }}
public class BMWTire implements Tire { @Override public void tire() { System.out.println("BMW Tire"); }}
public class AudiFactory extends CarFactory { @Override public Brake createBrake() { return new AudiBrake(); } @Override public Engine createEngine() { return new AudiEngine(); } @Override public Tire createTire() { return new AudiTire(); }}
public class BenzFactory extends CarFactory { @Override public Brake createBrake() { return new BenzBrake(); } @Override public Engine createEngine() { return new BenzEngine(); } @Override public Tire createTire() { return new BenzTire(); }}
public class BMWFactory extends CarFactory { @Override public Brake createBrake() { return new BMWBrake(); } @Override public Engine createEngine() { return new BMWEngine(); } @Override public Tire createTire() { return new BMWTire(); }}
在客户端中调用:
CarFactory mAudiFactory = new AudiFactory(); mAudiFactory.createBrake().brake(); mAudiFactory.createEngine().engine(); mAudiFactory.createTire().tire(); CarFactory mBMWFactory = new BMWFactory(); mBMWFactory.createBrake().brake(); mBMWFactory.createEngine().engine(); mBMWFactory.createTire().tire(); CarFactory mBenzFactory = new BenzFactory(); mBenzFactory.createBrake().brake(); mBenzFactory.createEngine().engine(); mBenzFactory.createTire().tire();
可以看到每个工厂的产品族的产品都创建了:
5.总结
抽象工厂模式在Android开发中使用得并不多,因为实际开发中很少会出现多个产品种类的情况,大部分情况使用工厂模式即可解决。
优点:
1).分离接口和实现,客户端使用抽象工厂来创建所需对象,但却并不知道具体的实现是谁,使其从产品的实现中解耦,更灵活。
缺点:
1).类的爆炸性增加,如果要增加一个工厂,那么相应的,就得增加一族产品。
2).不容易扩展新的产品类,因为当我们增加一个产品类时就需要修改抽象工厂,所以所有的具体工厂类也得对应修改。
Demo下载
- 《Android源码设计模式解析与实战》读书笔记(六)——抽象工厂模式
- 《Android源码设计模式解析与实战》读书笔记(五)——工厂方法模式
- 《Android源码设计模式解析与实战》读书笔记(六)
- 《Android源码设计模式解析与实战》读书笔记(二)——单例模式
- 《Android源码设计模式解析与实战》读书笔记(三)——建造者模式
- 《Android源码设计模式解析与实战》读书笔记(四)——原型模式
- 《Android源码设计模式解析与实战》读书笔记(七)——策略模式
- 《Android源码设计模式解析与实战》读书笔记(八)——状态模式
- 《Android源码设计模式解析与实战》读书笔记(九)——责任链模式
- 《Android源码设计模式解析与实战》读书笔记(十)——解释器模式
- 《Android源码设计模式解析与实战》读书笔记(十一)——命令模式
- 《Android源码设计模式解析与实战》读书笔记(十二)——观察者模式
- 《Android源码设计模式解析与实战》读书笔记(十三)——备忘录模式
- 《Android源码设计模式解析与实战》读书笔记(十四)——迭代器模式
- 《Android源码设计模式解析与实战》读书笔记(十五)——模板方法模式
- 《Android源码设计模式解析与实战》读书笔记(十六)——访问者模式
- 《Android源码设计模式解析与实战》读书笔记(十七)——中介者模式
- 《Android源码设计模式解析与实战》读书笔记(十八)——代理模式
- BeanUtils.populate的用法
- 算法题递归函数int mystrlen(char *buf, int N)是用来实现统计字符串中第一个空字符前面的字符长度。
- 多点触控 之 两个手指
- CoInitializeEx function
- 完整Java爬取起点小说网小说目录以及对应链接
- 《Android源码设计模式解析与实战》读书笔记(六)——抽象工厂模式
- 控件在代码设置宽度和高度。
- sql:常用sql查询工具五(explain 执行计划)
- 解决ScrollView中嵌套ListView或GridView导致的ScrollView自动滚动到ListView或GridView位置的问题
- 详谈jQuery中使用attr(), prop(), val()获取value的异同
- Hbuilder egit插件的安装使用--项目文件丢失的教训
- 【Java EE】--Contexts and Dependency Injection (上下文与依赖注入)04
- (个人总结)C++中int类型与String类型的相互转换
- Android开发之RecyclerView的交互动画(实现拖拽和删除)