0.工厂模式
工厂模式,同样作为创建型模式中较为容易的模式,我们在读懂前辈代码同时也能够很好的从其思想精髓中重构我们自己的代码,降低耦合。所以我们开始踩着前辈们巨大的肩膀,一路小跑了。
首先,来看简单工厂模式,通俗易懂,直接上代码:
1.简单工厂模式
public class Main {
public final static int PC_ACER=0;
public final static int PC_LENOVO=1;
public static void main(String[] args) {
PcFactory.producePc(PC_ACER).startLol();
PcFactory.producePc(PC_LENOVO).startLol();
// 运行结果
// Acer -- Triple kill -- 三杀
// Lenovo -- Penta kill -- 五杀
}
}
//打游戏的接口
interface PlayGameInterface {
void startLol();
}
//宏碁电脑
class AcerPc implements PlayGameInterface {
public void startLol() {
System.out.println("AcerPc -- Triple kill -- 三杀");
}
}
//联想电脑
class LenovoPc implements PlayGameInterface {
public void startLol() {
System.out.println("LenovoPc -- Penta kill -- 五杀");
}
}
//工厂类
class PcFactory {
public static PlayGameInterface producePc(int i) {
switch (i) {
case 0:
return new AcerPc();
case 1:
return new LenovoPc();
}
return null;
}
}
代码清晰透彻,就是两种PC都实现了打游戏功能,但具体实现不一样,我们在工厂类producePc()判断是哪一种电脑标识,返回不同的电脑,电脑运行英雄联盟的时候也就会执行自己复写的代码。这里可能大家就有疑问了,为啥我不直接new 一个pc出来,还要写什么鬼工厂类来过的对象,这不是多此一举嘛...
我们知道,代码跟着需求走,需求跟着市场走,我们作为底层农民只能一步步听文档的。那么问题来了,如果需求要改了,要用其他子类实例化了,是不是要把所有代码里的new都改掉,List list = new ArrayList / LinkList()。这样我们用工厂就只要在工厂类里面改就可以了。这也应了设计模式职能单一,就是Main类里面创建对象和使用对象-startLol 分开,降低了耦合度,使代码具备更高的拓展性和易维护性。
好,从上面简单工厂模式,我们肯定觉得low 爆了,这么简单,一点都不高大上,但它的作用是明显的。还有一点,如果后期,我们又要创建一个新的PC了,什么华硕、神舟呀,就要修改工厂类里面的代码,这违反了 设计模式的 开- 闭原则 。
所以强大的前辈们就搞出了 工厂方法,也可以理解为简单工厂模式是工厂模式的特殊类型。贴上代码,清晰透彻。
2.工厂方法 :
public class Main {
public final static int PC_ACER = 0;
public final static int PC_LENOVO = 1;
static PcFactoryInterface pcFactoryInterface;
public static void main(String[] args) {
pcFactoryInterface=new AcerFactory();
pcFactoryInterface.producePc().startLol();
pcFactoryInterface=new LenovoFactory();
pcFactoryInterface.producePc().startLol();
// 运行结果
// Acer -- Triple kill -- 三杀
// Lenovo -- Penta kill -- 五杀
}
}
// 打游戏的接口
interface PlayGameInterface {
void startLol();
}
// 宏碁电脑
class AcerPc implements PlayGameInterface {
public void startLol() {
System.out.println("Acer -- Triple kill -- 三杀");
}
}
// 联想电脑
class LenovoPc implements PlayGameInterface {
public void startLol() {
System.out.println("Lenovo -- Penta kill -- 五杀");
}
}
// 工厂接口
interface PcFactoryInterface{
PlayGameInterface producePc();
}
// 宏碁电脑的工厂
class AcerFactory implements PcFactoryInterface{
public PlayGameInterface producePc() {
return new AcerPc();
}
}
// 联想电脑的工厂
class LenovoFactory implements PcFactoryInterface{
public PlayGameInterface producePc() {
return new LenovoPc();
}
}
这不是和简单工厂一样的吗,就多写了工厂接口和每一种Pc的工厂类。咦,对哦,这样就不会影响以前的代码了,有需要新的电脑就可以再写个新的电脑类和工厂类了,就不违背开闭原则了,原来是这样。
时代在进步,我们出了新的一个类型 —— 手机。互联网公司为了能多赚钱就拓展了手机生产的业务。那作为公司的工厂它既要能够生产手机,又能够生产电脑。所有基于我们上面提到的工厂方法模式,前辈们对模式再一升级,这就是抽象工厂模式。
巨人的肩膀真广阔呀,真开心。赶紧的,看看巨人有什么好主意的,直接上代码。
3.抽象工厂模式:
public class Main {
public final static int PC_ACER = 0;
public final static int PC_LENOVO = 1;
static FactoryInterface factory;
public static void main(String[] args) {
factory=new AcerFactory();
factory.producePc().startLol();
factory.producePhone().shakeMore();
factory=new LenovoFactory();
factory.producePc().startLol();
factory.producePhone().shakeMore();
// 运行结果
// Acer -- Triple kill -- 三杀
// Acer -- 摇到 冰冰
// Lenovo -- Penta kill -- 五杀
// Lenovo -- 摇到 凤凤
}
}
// 打游戏的接口
interface PlayGameInterface {
void startLol();
}
// 玩微信的接口
interface UseWX{
//摇一摇功能
void shakeMore();
}
// 宏碁电脑
class AcerPc implements PlayGameInterface {
public void startLol() {
System.out.println("Acer -- Triple kill -- 三杀");
}
}
// 联想电脑
class LenovoPc implements PlayGameInterface {
public void startLol() {
System.out.println("Lenovo -- Penta kill -- 五杀");
}
}
// 宏碁手机
class AcerPhone implements UseWX{
public void shakeMore() {
System.out.println("Acer -- 摇到 冰冰");
}
}
// 联想手机
class LenovoPhone implements UseWX{
public void shakeMore() {
System.out.println("Lenovo -- 摇到 凤凤");
}
}
// 工厂接口
interface FactoryInterface{
PlayGameInterface producePc();
UseWX producePhone();
}
// 宏碁电脑的工厂
class AcerFactory implements FactoryInterface{
public PlayGameInterface producePc() {
return new AcerPc();
}
public UseWX producePhone() {
return new AcerPhone();
}
}
// 联想电脑的工厂
class LenovoFactory implements FactoryInterface{
public PlayGameInterface producePc() {
return new LenovoPc();
}
public UseWX producePhone() {
return new LenovoPhone();
}
}
由代码可知:我们的每一类型的手机都实现了玩微信的功能,微信可以摇一摇,我们的每一类型的手机都实现了玩微信的功能。工厂接口具备了生产手机的功能,每一品牌的工厂都实现这些生产能力。自然,如果后面我们出现了新的品牌了,比如苹果公司,那么我们就只要写出IPone 手机类,macBook 类以及生产它们的工厂类就可以了。
这就是工厂模式,那我们来总结一下:
- 简单工厂模式:各个产品独立,单一工厂类。多对一,在单一的工厂类里面判断需要什么产品就生产什么产品。注意静态方法。简单工厂模式比较简陋,后期拓展,更新麻烦,但如果遇到死都不改的代码,简单快速。
- 工厂方法:各个产品独立,各个工厂类独立。将工厂类抽象出来,具体产品具体工厂,多对多,在各自的工厂里面生产各自的产品,不需要更改工厂类,因为需要新的产品则创建新的工厂类。
- 抽象工厂:引入了类型概念,及不同产品的抽象,各个工厂具备生产不同类型产品的功能,工厂的能力更强大,高内聚。
我们再说说他们之间的联系和区别:
- 当抽象工厂只生产单一的产品,则退变成工厂方法。
- 当工厂方法只有一个工厂,则退变成简单工厂。