工厂方法模式:
使用工厂生产对象的形式代替直接使用new的方法生成对象;
为什么非要这样做呢?
使用工厂模式便于管理对象,方便代码维护管理;
光说是没有用的,下面使用代码来一波操作便于理解:
比如某个人想要理发,那么他可以是中分,左偏分或是右偏分;
下面使用代码来操作这个过程:
首先定义一个头发的接口:
/**
* 头发接口
*
* @author shion
*
*/
public interface HairInterface {
//这个表示想要什么头型,由子类实现
void draw();
}
下面是三个实现类,
public class CenterHiarInterface implements HairInterface {
@Override
public void draw() {
System.out.println("-----------------中分----------------");
}
}
public class LeftHiarInterface implements HairInterface {
@Override
public void draw() {
System.out.println("-----------------左偏分----------------");
}
}
public class RightHiarInterface implements HairInterface {
@Override
public void draw() {
System.out.println("-----------------右偏分----------------");
}
}
现在比如我想要一个中分,那么就可以如下来写代码:
public class Test {
public static void main(String[] args) {
//使用new的方式来创建对象,这种方式其实不可去
HairInterface hair = new CenterHiarInterface();
hair.draw();
}
}
上面是我们经常使用的方式来创建对象方式,其实他是有弊端的:
如果我们的项目工程大了,使用这个对象的地方有少说有30多出处吧,多了也不夸张了,哈啊;现在老板说了,这里你不要做成中分,你做成光头吧,好了,这个时候你要将上面的CenterHiarInterface全部修改掉,这是不是很无语,改个需求,工作量也变大了,因为工程项目大,还要小心翼翼,生怕出现奇葩漏改了,那就坑了;即使是将中分改成右偏分,你也会工作量大,这个时候我们思考一下,有没有合适的方式呢,当时当然有的,就是我们下面要采取的工厂模式;
我们先创建一个头发工厂类;
public class HairFactory {
public static HairInterface getHair(String hair) {
if ("center".equalsIgnoreCase(hair)) {
// 生成一个中分的
return new CenterHiarInterface();
} else if ("right".equalsIgnoreCase(hair)) {
// 生产一个右偏分的
return new RightHiarInterface();
} else if ("left".equalsIgnoreCase(hair)) {
// 生产一个右偏分的
return new LeftHiarInterface();
}
// 默认无需发型
return new HairInterface() {
@Override
public void draw() {
System.out.println("--------------我什么发型也不要-------------");
}
};
}
}
添加到测试类中如下:
public class Test {
public static void main(String[] args) {
// 使用new的方式来创建对象,这种方式其实不可去
HairInterface hair = new CenterHiarInterface();
hair.draw();
//使用工厂模式跟上边对照
HairInterface newHair = HairFactory.getHair("center");
newHair.draw();
}
}
可以看到我们使用工厂模式之后即使是要把中分换成光头,我们这里没有必要修改,要修改的话,我们只是修改哪一个工厂类HairFactory就可以(把那个中分的用代码注释一下,改成返回自己实现的光头强的就可以啦)
通过工厂方法返回一个一个产品,这个方式很想工厂流水线,所以顾名思义是工厂模式;它的好处是显而易见的;
但是上面只是最普通的工厂模式;还有抽象工厂模式;反正不管什么工厂反正都要有返回;
抽象工厂模式:
上面是对人,假设现在有一个宠物猫,它也要理发,也可以修成中分,左偏分,左偏分,那么我们是不是可以按照我们上面的那种写法在重写一遍;
猫的头发接口:
public interface CatHairInterface {
void onCatDraw();
}
两个实现类(只是左右)
public class LeftCatHairInterface implements CatHairInterface {
@Override
public void onCatDraw() {
System.out.println("-----------------LeftCatHairInterface------------------------");
}
}
public class RightCatHairInterface implements CatHairInterface {
@Override
public void onCatDraw() {
System.out.println("-----------------RightCatHairInterface------------------------");
}
}
生产猫头发的工厂类:
public class CatHairFactory {
public static CatHairInterface getHair(String key) {
if ("left".equals(key)) {
return new LeftCatHairInterface();
} else if ("right".equals(key)) {
return new RightCatHairInterface();
} else {//还有就继续添加
}
return new CatHairInterface() {
@Override
public void onCatDraw() {
System.out.println("默认空的实现!");
}
};
}
}
现在又来个机器人,也要弄中分,右偏分,左偏分,那么我们要在写一遍了,等等吧;
这些一个个工厂实力对象生产了,但实际的编程中,我们期望的是面向接口,而不是面向这些具体的实力类,这样可以拥抱变化,
像上面的那种不同的产品类比如人,动物,机器人等等,有相同的特性比如中分,右偏分,左偏分,生产这些产品的工厂类,我们可以抽象出一个公共工厂的接口 比如:
public interface IFactory {
//人
public HairInterface getHairInterface();
//宠物猫
public CatHairInterface getCatHairInterface();
}
我们按照功能实现工厂实例:
public class LeftFactory implements IFactory {
@Override
public HairInterface getHairInterface() {
return new LeftHairInterface();
}
@Override
public CatHairInterface getCatHairInterface() {
return new LeftCatHairInterface();
}
}
public class RightFactory implements IFactory {
@Override
public HairInterface getHairInterface() {
return new RightHairInterface();
}
@Override
public CatHairInterface getCatHairInterface() {
return new RightCatHairInterface();
}
}
上面就是我对抽象工厂模式的理解;