Android设计模式-5-抽象工厂模式
2018-06-04 本文已影响43人
今阳说
1. 定义:
- 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;由具体的工厂负责实现具体的产品实例。
- 与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类
- 可以理解为工厂模式只有一个维度,就是同一产品类下的不同产品;而抽象工厂模式有两个维度,不同的产品族和每个产品族下不同的产品
2. 优缺点
- 优点:
- 降低耦合,将具体产品的创建延迟到具体工厂的子类中
- 易于扩展,新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
- 有利于产品的一致性
- 不使用静态工厂方法,可以形成基于继承的等级结构。
- 缺点:当需要新增产品族时,需要修改工厂基类,不符合开闭原则
- 对于新的产品种类符合开-闭原则, 对于新的产品族不符合开-闭原则, 这一特性称为开-闭原则的倾斜性。
3. 实例演示:
以电脑及外设的厂商为例
- 首先是产品的基类
//电脑
abstract class Pc {
public abstract void display();
}
//键盘
abstract class Keyboard {
public abstract void display();
}
//鼠标
abstract class Mouse {
public abstract void display();
}
- 然后创建工厂基类
abstract class BaseFactory {
public abstract Pc newPc();
public abstract Keyboard newKeyBoard();
public abstract Mouse newMouse();
}
- 具体的产品类 戴尔的电脑和外设
class DellPc extends Pc {
@Override
public void display() {
LjyLogUtil.i("戴尔电脑");
}
}
class DellKeyboard extends Keyboard {
@Override
public void display() {
LjyLogUtil.i("戴尔键盘");
}
}
class DellMouse extends Mouse {
@Override
public void display() {
LjyLogUtil.i("戴尔鼠标");
}
}
- 具体的工厂类 戴尔工厂
class DellFactory extends BaseFactory {
@Override
public Pc newPc() {
return new DellPc();
}
@Override
public Keyboard newKeyBoard() {
return new DellKeyboard();
}
@Override
public Mouse newMouse() {
return new DellMouse();
}
}
5.使用具体的工厂类创建产品
private void methodAbstractFactoryPattern() {
DellFactory dellFactory=new DellFactory();
dellFactory.newPc().display();
dellFactory.newKeyBoard().display();
dellFactory.newMouse().display();
}
- 当新增具体产品,如华为电脑和外设时,只需通过继承产品基类创建具体的产品类,继承工厂基类创建具体的工厂类即可
class HuaWeiPc extends Pc {
@Override
public void display() {
LjyLogUtil.i("华为电脑");
}
}
class HuaWeiKeyboard extends Keyboard {
@Override
public void display() {
LjyLogUtil.i("华为键盘");
}
}
class HuaWeiMouse extends Mouse {
@Override
public void display() {
LjyLogUtil.i("华为鼠标");
}
}
class HuaWeiFactory extends BaseFactory {
@Override
public Pc newPc() {
return new HuaWeiPc();
}
@Override
public Keyboard newKeyBoard() {
return new HuaWeiKeyboard();
}
@Override
public Mouse newMouse() {
return new HuaWeiMouse();
}
}
- 若想新增一个产品族,如耳机,则需要增加新的产品基类,并修改工厂基类,然后实现具体的产品类和工厂类
- 实际应用时,可以以工厂基类作为参数类型,用户根据需要选择不同的工厂类,这样既不影响程序的内部逻辑,又可以满足用户的定制需求,例如网络请求框架Retrofit的实例创建,经常会这样写:
retrofit = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.client(getOkHttpClient())//配置okhttp
.addConverterFactory(GsonConverterFactory.create())//支持gson
.addConverterFactory(SimpleXmlConverterFactory.create())//支持xml
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//增加返回值为Oservable<T>的支持,RxJava
.build();
那么上面5中的调用就可以这样写:
首先创建一个外设商店
class ComputerShop{
BaseFactory factory;
public void setFactory(BaseFactory factory) {
this.factory = factory;
}
public Pc getPc(){
return factory.newPc();
}
public Keyboard getKeyboard(){
return factory.newKeyBoard();
}
public Mouse getMouse(){
return factory.newMouse();
}
}
然后可以给他设置不同的factory,来得到不同的产品
ComputerShop computerShop=new ComputerShop();
computerShop.setFactory(new HuaWeiFactory());
computerShop.getPc();
computerShop.getKeyboard();
computerShop.getMouse();