上一篇我们介绍了关于使用公模做手机的事情,但有个问题就是不能高度定制,现在我们来介绍下我的抽象工厂方法,他可以做到的定制就很高啦,既可以造飞机,汽车,又可以做苹果手机等等。
一般能处理这类问题的,都是些大厂家,这类大厂家就很规范,分工明确的,而且也有很多流水线,代工不少产品,为了降低风险同时提营业额嘛,好懂。
假设有一家叫 NiuBi
的公司,他很厉害,有多条流水线,一条生产火箭,一条生产苹果机,一条生产汽车的。能加工这么广的是厉害。
面对一个这么厉害的厂,我们需要更高的抽象,现在来展示下怎么写这个厂。
代码实现
我们先写一个基本的设备抽象工厂,这个工厂是所有流水线的基础,
public abstract class AbstractFactory implements FactoryMethond {
public BaseDevice createDevice(String name) {
BaseDevice phone = null;
try {
phone = (BaseDevice) Class.forName(name).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return phone;
}
}
public interface FactoryMethond {
public BaseDevice createDevice(String name);
}
我们的抽象工厂很简单,就是根据提供的名字去生产这个设备。
我们对所有能生产的东西都抽象成一个最基本的设备类BaseDevice
。
public interface BaseDevice {
void charge();
void showBrand();
void startUp();
void shutDown();
}
为了方便说明,这里就在原有基础上加多一个充电的接口charge()
,这个就是我们高度定制的其中一个点啦,例如有的设备是充电,有的充油,还有一些充气的等等。
有了这样的基础,我们就可以来大展身手,定义我们的几条流水线了。
我们先来一条手机的流水线
public class PhoneFactory extends AbstractFactory{
public Apple4sDevice create4s(){
return (Apple4sDevice) super.createDevice(Apple4sDevice.class.getName());
}
public Apple7sDevice create7s(){
return (Apple7sDevice) super.createDevice(Apple7sDevice.class.getName());
}
}
我们的手机流水线目前提供制造4s和7s型号。
接着我们来多一个火箭的生产线
public class RocketFactory extends AbstractFactory{
public RocketADevice createRocketA(){
return (RocketADevice) super.createDevice(RocketADevice.class.getName());
}
public RocketBDevice createRocketB(){
return (RocketBDevice) super.createDevice(RocketBDevice.class.getName());
}
}
这样我们的两条实例流水线就搭建好了,是时候来试着生产点内容啦,好了,我们来始终运行下。
public class Client {
public static void main(String[] args) {
RocketFactory rocketFactory = new RocketFactory();
BaseDevice baseDevice = rocketFactory.createRocketA();
baseDevice.showBrand();
PhoneFactory phoneFactory = new PhoneFactory();
Apple4sDevice apple4s = phoneFactory.create4s();
apple4s.showBrand();
}
}
我们的示例如上,成功的为我们生产了设备,打印了下面的内容
tesla rocket
Apple Phone
好了,我们的抽象工厂的介绍就到这里啦。
不要觉得短暂,很快就看完了这个抽象工厂的核心内容!
下面贴下别的几个类
这个是我们的所有火箭的基础
public abstract class RocketDevice implements BaseDevice {
@Override
public void showBrand() {
System.out.println("tesla rocket");
}
@Override
public void startUp() {
System.out.println("engine on");
}
@Override
public void shutDown() {
System.out.println("rocket is sleeping");
}
}
有了他,我们改造就很简单啦,两个火箭A和B
public class RocketADevice extends RocketDevice {
@Override
public void charge() {
System.out.println("using electric");
}
}
public class RocketBDevice extends RocketDevice{
@Override
public void charge() {
System.out.println(" using oil");
}
}
然后我们的苹果机也类似的:
public abstract class AppleDevice implements BaseDevice {
@Override
public void showBrand() {
System.out.println("Apple Phone");
}
@Override
public void startUp() {
System.out.println("power on");
}
@Override
public void shutDown() {
System.out.println("power off");
}
}
我们的4s手机和7s手机
public class Apple4sDevice extends AppleDevice {
@Override
public void charge() {
System.out.println("electric");
}
}
public class Apple7sDevice extends AppleDevice {
@Override
public void charge() {
System.out.println("usb 4");
}
}
好了,这样我们的就全部贴出来了
类图
这个就是我们的类图啦
我们的Client去调用我们的工厂去生产我们想要的产品。
不过这个图和我们的有一点不一样啊。我们的两个抽象产品都是同源的,实现了BaseDevice
,这里没体现出来。
另外我们的抽象产品有个名字叫产品等级,我们有两个,一个手机,一个火箭的。
我们的具体的产品也又个名字叫产品族,在我们的例子有4s,7s和火箭A/B。
后记
有了抽象工厂这大杀器,以后我们需要修改的就是基础我们的基础设备,再开一条流水线来生产就好了。高内聚,低耦合和ocp原则得到了很好的体现。
前面话这么说,当然是有问题的,那是在不添加产品族的情况。
如果要添加新的产品族的话,我们要改动的不少内容,如果我们选择不去在原有类的基础上添加新的方法,我们只能去继承,当有多个产品以此添加,我们就得到了很多的继承关系,这就不得了了。
但相对的添加产品等级就容易一些了,因为开一条新的相对不影响旧的内容的。
不过不得不说的是,在我的实际开发的安卓项目中,这个模式用的还是挺少的,目前我都记不起来曾经在哪里用过了。