工厂模式,从字面上理解就是设计一个工厂来生产产品,用户往工厂中投入原料,工厂就给用户生产出来相应的产品,用户无需知道产品具体的生产过程。
根据以上定义,我们就来设计一个自己的工厂类——手机工厂。
<span style="font-size:14px;">/**
* Created by leevi on 16/10/8.
*/
public class MobilePhoneFactory {
public static MobilePhone produce(String name){
if (name.equals("xiaomi")){
return new XiaomiMobilePhone();
}else if (name.equals("华为")){
return new HuaweiMobilePhone();
}else if (name.equals("苹果")){
return new Iphone();
}else {
Log.d("MobilePhoneFactory", "你看你给的啥原料啊,创建不出来!!!");
return null;
}
}
}</span>
当我们要使用该工厂类的时候,我们只需要调用工厂类中的静态方法传入相应的参数即可:
<span style="font-size:14px;">MobilePhoneFactory.produce("小米");</span>
以上写法就是“简单工厂模式”,它的优点是:用户只需要传入相应的参数就能生产出各种各样的产品,不需要知道具体的生产逻辑。但是它的缺点也是很明显的:1、不符合面向对象设计的“单一职责”原则,一个手机工厂可以生产各种各样的手机。2、不符合面向对象设计的“开放封闭原则”,如果现在多了一种三星手机要生产,那我们又得修改我们的工厂类,增加一个判断语句。
为了改进“简单工厂”模式的缺点,我们设计出了一种工厂方法模式——定义一个创建对象的接口(抽象工厂类),让其子类(具体工厂类)去决定实例化哪个类(具体产品类)。一个工厂实现一种产品,一对一的关系。那我们就来改进一下我们的代码:
先定义一个抽象工厂类:
<span style="font-size:14px;">/**
* Created by leevi on 16/10/8.
*/
public abstract class MobilePhoneFactory {
public abstract MobilePhone produce();
}</span>
再针对各种品牌的手机,定义不同的手机工厂:
<span style="font-size:14px;">public class XiaomiPhoneFactory extends MobilePhoneFactory{
@Override
public MobilePhone produce() {
return new XiaomiMobilePhone();
}
}</span>
<span style="font-size:14px;">/**
* Created by leevi on 16/10/8.
*/
public class HuaweiPhoneFactory extends MobilePhoneFactory{
@Override
public MobilePhone produce() {
return new HuaweiMobilePhone();
}
}</span>
怎么样来生产各种各样的手机呢?
<span style="font-size:14px;">XiaomiPhoneFactory xiaomiPhoneFactory = new XiaomiPhoneFactory();
XiaomiMobilePhone xiaomiPhone = (XiaomiMobilePhone) xiaomiPhoneFactory.produce();</span>
工厂方法模式的优点很明显:符合“单一职责”和“开发—封闭原则”,一个工厂类只生产一种类型的产品、有了新的产品不用修改原有工厂而是重新创建一个工厂来生产。
但是它的缺点也是很明显的:类太多啦,要生产一类型产品要有四个类(抽象工厂类、具体工厂类、抽象产品类、具体产品类),导致项目过于臃肿。
为了改进“工厂方法模式”的缺点,我们设计出了“抽象工厂模式”:提供一个创建一系列相关或者相互依赖产品的接口,而无需制定他们的具体类,一对多的关系。抽象工厂模式是工厂方法模式的升级版。小米手机工厂可以生产大屏小米手机、中屏小米手机、小屏小米手机,华为手机工厂可以生产大屏华为、中屏华为手机、小屏华为手机等,苹果手机厂可以生产大屏、中屏、小屏Iphone手机。代码将做如下修改:
抽象工厂类:
<span style="font-size:14px;">/**
* Created by leevi on 16/10/8.
*/
public abstract class MobilePhoneFactory {
public abstract BigPhone produceBigPhone();
public abstract MiddlePhone produceMiddlePhone();
public abstract SmallPhone produceSmallPhone();
}</span>
大屏手机抽象类:
public abstract class BigPhone extends MobilePhone{
@Override
public abstract void call();
@Override
public int getSize() {
return 40;
}
}
小屏手机抽象类
public abstract class SmallPhone extends MobilePhone{
@Override
public abstract void call();
@Override
public int getSize() {
return 20;
}
}
小米手机厂
/**
* Created by leevi on 16/10/8.
*/
public class XiaomiPhoneFactory extends MobilePhoneFactory{
@Override
public MobilePhone produceBigPhone() {
return new BigXiaomiPhone();
}
@Override
public MobilePhone produceMiddlePhone() {
return new MiddleXiaomiPhone();
}
@Override
public MobilePhone produceSmallPhone() {
return new SmallXiaomiPhone();
}
}
用法如下:
XiaomiPhoneFactory xiaomiPhoneFactory = new XiaomiPhoneFactory();
BigXiaomiPhone BigXiaomiPhone = xiaomiPhoneFactory.produceBigPhone();
MiddleXiaomiPhone middleXiaomiPhone = xiaomiPhoneFactory.produceMiddlePhone();
SmallXiaomiPhone smallXiaomiPhone = xiaomiPhoneFactory.produceSmallPhone();
“抽象工厂模式”
即符合面向对象设计的“开闭原则”和“单一职责原则”。又减少了系统中的类的数量,不用像工厂方法一样每生产一个产品都要有一个具体的工厂类。