LK计划接下来的一段时间,来重点学习一下设计模式。当然LK不会把每种设计模式都讲一遍,经常使用到的设计模式才是LK要跟大家分享的重点。LK的设计模式学习之路,主要弄清楚以下几个问题:
- 这种模式是干啥的
- 这种模式怎么用
- 能解决什么问题
- 有什么应用场景
- 用它有什么优势
听着LK这样一说,我不禁开始有所感慨,这个问题让我想起了哲学的基本问题,你从哪里来,要到哪里去。中间过程只不过是短短数十载,留给你自己去体会。哈哈,又开始瞎扯淡了。
那么LK为什么要学习设计模式呢?答案很简单,LK不想让自己写的代码如此的繁琐,if~else满屏幕飞,LK也想让自己的代码充满智慧的光芒。当然学习设计模式也有助于理解源码。体会开源大神的杰作。我们总是听人说读一本自己喜爱的书就好像是与作者在书中对话,我真的很羡慕这样的人,但是我好像从来没有过这样的体会。那我觉得设计模式就是程序的思想,大量的程序逐渐清晰的产生了现在我们熟知的设计模式。只有掌握这些你才能在程序的世界里和大神对话。
来看看LK即将要说的工厂模式,提到工厂我们就会想到富士康。不仅是工厂还是跨国工厂。其实工厂模式和现实的工厂是一样的,不同的工厂生产不同的产品,同一个工厂也可以生产不同的产品。有点像多啦a梦的大口袋,要啥有啥。多啦A梦LK童年的会议。我们的工厂设计模式也是一样,由工厂产生所需要的对象,或者由大工厂产生小工厂,在由小工厂产生对象。万物皆对象,真实工厂造就万物,程序工厂造就所有对象。
LK就以造汽车来和大家聊一聊工厂模式,很简单一间工厂,生产法拉利和劳斯莱斯。
来看看类图
来看看具体实现
接口生产的汽车
package factory;
public interface Car {
//加油
void oil();
}
实现类法拉利
/**
* 具体产品---法拉利
* @author yrz
*
*/
public class Ferrari implements Car{
public void oil() {
System.out.println("法拉利-----正在加油");
}
}
实现类劳斯莱斯
/**
* 具体实现类劳斯莱斯
* @author yrz
*
*/
public class RollsRoyce implements Car{
public void oil() {
System.out.println("劳斯莱斯------正在加油");
}
}
汽车生产工厂
/**
* 汽车工厂用于生产具体汽车
* @author yrz
*
*/
public class CarFactory {
public Car createCar(String carType) {
if (carType == null) {
return null;
}
if (carType.equalsIgnoreCase("Ferrari")) {
return new Ferrari();
} else if (carType.equalsIgnoreCase("RollsRoyce")) {
return new RollsRoyce();
}
return null;
}
}
测试类
public class FactoryPatternDemo {
public static void main(String[] args) {
CarFactory carFactory = new CarFactory();
// 生产劳斯莱斯
Car car1 = carFactory.createCar("RollsRoyce");
car1.oil();
// 生产法拉利
Car car2 = carFactory.createCar("Ferrari");
car2.oil();
}
}
运行结果:
到此我们的法拉利和劳斯莱斯就造好了,加满油就可以上路了。
可以看到只要我们知道要生产什么类型的车,就可以由工厂去生产。
问题来了,我要生产车,就需要生产车的零件。而且一些特殊的零件还要去其它国家采购,而现在我们都是在用现有的零件直接组装。所以现有工厂就显然不够用了。
抽象工厂的概念就应用产生。LK理解的抽象工厂就是已有工厂的再次抽象,一种是大工厂下面的小工厂,另一种是前者工厂和后者工厂有很大的联系。
还是以生产汽车为例,这次LK添加了生产外壳,轮子,引擎的三个工厂。再由每个生产零件的子工厂生产法拉利和劳斯莱斯各自需要的零件。
来看看具体实现类
发动机接口
/**
* 发动机
* @author yrz
*
*/
public interface Engine {
void dosomething();
}
外壳接口
/**
* 外壳
* @author yrz
*
*/
public interface Shell {
void dosomething();
}
轮子接口
/**
* 轮子
* @author yrz
*
*/
public interface Wheel {
void dosomething();
}
抽象工厂类
/**
* 总的组装工厂
* @author yrz
*
*/
public abstract class AbstractFactory {
//组装所需-----引擎
abstract Engine getEngine(String engine);
//组装所需-----轮子
abstract Wheel getWheel(String wheel);
//组装所需----外壳
abstract Shell getShell(String shell);
}
发动机工厂
/**
* 引擎子工厂
*
* @author yrz
*
*/
public class EngineFactory extends AbstractFactory {
@Override
Engine getEngine(String engine) {
if (engine == null) {
return null;
}
if (engine.equalsIgnoreCase("FerraEngine")) {
return new FerraEngine();
} else if (engine.equalsIgnoreCase("RollsRoyceEngine")) {
return new RollsRoyceEngine();
}
return null;
}
@Override
Wheel getWheel(String wheel) {
return null;
}
@Override
Shell getShell(String shell) {
return null;
}
}
轮子工厂
/**
* 轮子子工厂
* @author yrz
*
*/
public class WheelFactory extends AbstractFactory{
@Override
Engine getEngine(String engine) {
return null;
}
@Override
Wheel getWheel(String wheel) {
if (wheel == null) {
return null;
}
if (wheel.equalsIgnoreCase("FerraWheel")) {
return new FerraWheel();
} else if (wheel.equalsIgnoreCase("RollsRoyceWheel")) {
return new RollsRoyceWheel();
}
return null;
}
@Override
Shell getShell(String shell) {
return null;
}
}
外壳工厂
/**
* 外壳子工厂
* @author yrz
*
*/
public class ShellFactory extends AbstractFactory{
@Override
Engine getEngine(String engine) {
// TODO Auto-generated method stub
return null;
}
@Override
Wheel getWheel(String wheel) {
// TODO Auto-generated method stub
return null;
}
@Override
Shell getShell(String shell) {
if (shell == null) {
return null;
}
if (shell.equalsIgnoreCase("FerraShell")) {
return new FerraShell();
} else if (shell.equalsIgnoreCase("RollsRoyceShell")) {
return new RollsRoyceShell();
}
return null;
}
}
工厂生产类
/**
* 生产子工厂
*
* @author yrz
*
*/
public class FactoryProducer {
static AbstractFactory getFactory(String factoryType) {
if (factoryType == null) {
return null;
}
if (factoryType.equalsIgnoreCase("Engine")) {
return new EngineFactory();
} else if (factoryType.equalsIgnoreCase("Wheel")) {
return new WheelFactory();
} else if (factoryType.equalsIgnoreCase("Shell")) {
return new ShellFactory();
}
return null;
}
}
测试类
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
// 获取引擎工厂
AbstractFactory engineFactory = FactoryProducer.getFactory("Engine");
// 获取具体引擎
Engine feEngine = engineFactory.getEngine("FerraEngine");
feEngine.dosomething();
Engine roEngine = engineFactory.getEngine("RollsRoyceEngine");
roEngine.dosomething();
System.out.println("--------------------------");
// 获取轮子工厂
AbstractFactory wheelFactory = FactoryProducer.getFactory("Wheel");
// 获取具体轮子
Wheel feWheel = wheelFactory.getWheel("FerraWheel");
feWheel.dosomething();
Wheel roWheel = wheelFactory.getWheel("RollsRoyceWheel");
roWheel.dosomething();
System.out.println("--------------------------");
// 获取外壳工厂
AbstractFactory shellFactory = FactoryProducer.getFactory("Shell");
// 获取具体外壳
Shell feShell = shellFactory.getShell("FerraShell");
feShell.dosomething();
Shell roShell = shellFactory.getShell("RollsRoyceShell");
roShell.dosomething();
}
}
运行结果:
这里就省略了具体零件实现类,有兴趣可以根据我的类图和运行结果自己尝试。
是不是对工厂有了新的认识。
总结一下
写到这,LK前段时间写过spring IOC源码理解,可以看到BeanFactory中实际是一个hashmap,key存放着每一个创建的bean name。获取具体工厂时只需要bean的name即可,和我们要生产什么类型的零件输入零件名称,想要生产什么类型的car输入car的类型是一个道理。感兴趣可以去看看LK的那片文章。