工厂模式
首先来看传统的设计模式
现在有一个需求:生产 小米手机
手机接口
//手机接口
public interface Phone {
void make();
}
小米手机类
//小米手机类
public class MiPhone implements Phone {
public MiPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi phone!");
}
}
测试
public class Demo {
public static void main(String[] arg) {
String phoneType = "MiPhone";
Phone miPhone = null;
if(phoneType.equalsIgnoreCase("MiPhone")){
Phone miPhone = new MiPhone();
}
}
}
以上,通过传统的方式,我们很容易就可以实现需求,但是现在需求需要扩展,比如需要添加生产IPhone手机,如果采取上述方式的话,IPhone类一定是必不可少的,但是在使用的时候就需要添加如下这行代码。
else if(phoneType.equalsIgnoreCase("iPhone")) {
return new IPhone();
}
然后就可以完成新增的需求,但是如果订购手机不仅在这里使用到,那就需要在另一个使用它的地方也修改对应代码,这样就不易扩展,因此,我们想到一个办法,把 new 手机的方法都放在一个类中,也就是我们说的Factory。就开始了下面的简单工厂模式
一、简单工厂模式
我们仍然使用上述需求书写代码
首先,我们新增IPhone类
IPhone类
//IPhone类
public class IPhone implements Phone {
public IPhone() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make iphone!");
}
}
其次,我们把上面new 手机的操作统一到一个类(Factory)中
PhoneFactory类
//PhoneFactory类
public class PhoneFactory {
public Phone makePhone(String phoneType) {
if(phoneType.equalsIgnoreCase("MiPhone")){
return new MiPhone();
}
else if(phoneType.equalsIgnoreCase("iPhone")) {
return new IPhone();
}
return null;
}
}
最后,在测试类中,new Factory()实例,再调用factory的生产手机的方法,就可以得到对应手机
测试类
public class Demo {
public static void main(String[] arg) {
PhoneFactory factory = new PhoneFactory();
MiPhone miPhone = (MiPhone)factory.makePhone("MiPhone"); // make xiaomi phone!
IPhone iPhone = (IPhone)factory.makePhone("iPhone"); // make iphone!
}
}
这样一来,后续我们需要扩展新的手机类型的时候,只需要新增手机类,并且只用修改Factory类即可,便于扩展。
二、工厂方法模式
和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂。也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。
接下来继续使用生产手机的例子来讲解该模式。
其中和产品相关的Phone类、MiPhone类和IPhone类的定义不变。
首先,我们创建抽象工厂AbstractFactory接口,该接口并不具体
AbstractFactory
public interface AbstractFactory {
Phone makePhone();
}
然后,创建对应手机工厂实现接口
XiaoMiFactory
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
}
AppleFactory
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
}
测试
public class Demo {
public static void main(String[] arg) {
AbstractFactory miFactory = new XiaoMiFactory();
AbstractFactory appleFactory = new AppleFactory();
miFactory.makePhone(); // make xiaomi phone!
appleFactory.makePhone(); // make iphone!
}
}
以上,我们就可以不用在工厂类中指定具体的类型,只需要继承超级工厂,由指定子类创建相应的手机就可以。
三、抽象工厂模式
上述方式可以很好的解决我们目前的需求,但是还有更深层次的需求,如果我们不仅要生产手机,还要生产电脑等等,那怎么办;其实还可以通过上述方式实现,只不过需要多增加一个超级工厂,再添加对应实现类,这样显然不容易扩展。因此,我们就想到了另一种方式,通过一个超级工厂
,里面可以声明多种生产方法
,不仅是手机还是电脑,指定品牌工厂实现类后,实现相应的生产手机和电脑的方法就可以实现这个需求。
首先,PC类相关
public interface PC {
void make();
}
public class MiPC implements PC {
public MiPC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make xiaomi PC!");
}
}
public class MAC implements PC {
public MAC() {
this.make();
}
@Override
public void make() {
// TODO Auto-generated method stub
System.out.println("make MAC!");
}
}
然后,修改超级工厂
public interface AbstractFactory {
Phone makePhone();//生产手机
PC makePC();//生产PC电脑
}
其次,品牌类实现相应接口
public class XiaoMiFactory implements AbstractFactory{
@Override
public Phone makePhone() {
return new MiPhone();
}
@Override
public PC makePC() {
return new MiPC();
}
}
public class AppleFactory implements AbstractFactory {
@Override
public Phone makePhone() {
return new IPhone();
}
@Override
public PC makePC() {
return new MAC();
}
}
测试
public class Demo {
public static void main(String[] arg) {
AbstractFactory miFactory = new XiaoMiFactory();
AbstractFactory appleFactory = new AppleFactory();
miFactory.makePhone(); // make xiaomi phone!
miFactory.makePC(); // make xiaomi PC!
appleFactory.makePhone(); // make iphone!
appleFactory.makePC(); // make MAC!
}
}