工厂模式(Factory Pattern):方便用来管理并创建有同一父类的对象的模式
假设我们是一个飞机制造商,客户现在向我们定制飞机。
而制造飞机的第一步,首先要知道什么是飞机。它有哪些功能,比如说:飞、导航。那我们先定义一套标准,暂不考虑实现:
//定义一个飞机接口,即标准
public interface Plain {
//飞
public void fly();
//导航
public void navigation();
}
既然标准已经制定好,那么我们开始研发飞机。先研发出播音777,为后面批量生产做准备:
//播音777载客飞机
public class Boeing777 implements Plain {
public void fly() {
System.out.println("播音777-飞");
}
public void navigation() {
System.out.println("播音777-导航");
}
}
再研发出阿帕奇直升机:
//阿帕奇直升机
public class Apache implements Plain {
public void fly() {
System.out.println("阿帕奇-飞");
}
public void navigation() {
System.out.println("阿帕奇-导航");
}
}
这两种飞机我们已经可以研发出来了,如果要批量去制造,还需要定义并规划飞机工厂的工作:
//定义飞机工厂
public class PlainFactory {
//造出不同类型飞机的方法
public Plain getPlain(String plainType){
if(plainType==null){
return null;
}
if(plainType.equals("Boeing777")){
return new Boeing777();
}else if(plainType.equals("Apache")){
return new Apache();
}else{
return null;
}
}
}
飞机和飞机工厂已经有能力研发出来了,只需等待资金启动,我们实际去建造飞机工厂,并且造出真正的飞机:
//客户给钱后,先建造工厂,再造飞机
public class Customer {
public static void main(String[] args) {
//建造真正的飞机工厂
PlainFactory factory = new PlainFactory();
//用飞机工厂制造播音777
Plain boeing777 = factory.getPlain("Boeing777");
boeing777.fly();
boeing777.navigation();
//用飞机工厂制造出阿帕奇
Plain apache = factory.getPlain("Apache");
apache.fly();
apache.navigation();
}
}
飞机已经造好,检验飞机是否能够正常运行。这是简单工厂模型,结果客户满意:
播音777-飞
播音777-导航
阿帕奇-飞
阿帕奇-导航
当然,如果客户不想花钱在飞机工厂上,只想要飞机,我们只好先建好自己的工厂,客户给钱,我们只需生产飞机:
//创建静态飞机工厂
public class PlainFactory {
//加static是变成类方法,等于我们有属于自己的飞机工厂,而不用每次都去建造了
public static Plain getPlain(String plainType){
if(plainType==null){
return null;
}
if(plainType.equals("Boeing777")){
return new Boeing777();
}else if(plainType.equals("Apache")){
return new Apache();
}else{
return null;
}
}
}
//客户给钱后,因为我们有自己的工厂,现在只需要造飞机了
public class Customer {
public static void main(String[] args) {
//用自己的飞机工厂制造播音777
Plain boeing777 = PlainFactory.getPlain("Boeing777");
boeing777.fly();
boeing777.navigation();
//用自己的飞机工厂制造出阿帕奇
Plain apache = PlainFactory.getPlain("Apache");
apache.fly();
apache.navigation();
}
}
这是静态工厂模型,结果一致:
播音777-飞
播音777-导航
阿帕奇-飞
阿帕奇-导航
由于造飞机,拿到了利润,而我们不甘贫穷,想要发展副业,比如造大炮,那该怎么办呢?目前已经一整套造飞机的方法,不妨借鉴一下。
//定义一个大炮接口,Gun.java
public interface Gun {
//瞄准
public void aim();
//发射
public void shoot();
}
//迫击炮,Mortar.java
public class Mortar implements Gun {
public void aim() {
System.out.println("迫击炮-瞄准");
}
public void shoot() {
System.out.println("迫击炮-发射");
}
}
//榴弹炮,Howitzer.java
public class Howitzer implements Gun {
public void aim() {
System.out.println("榴弹炮-瞄准");
}
public void shoot() {
System.out.println("榴弹炮-射击");
}
}
//创建自己的大炮工厂,GunFactory.java
public class GunFactory {
//根据需要建造出大炮
public static Gun getGun(String gunType){
if(gunType==null){
return null;
}
if(gunType.equals("Mortar")){
return new Mortar();
}else if(gunType.equals("Howitzer")){
return new Howitzer();
}else{
return null;
}
}
}
//客户给钱后,Customer.java
public class Customer {
public static void main(String[] args) {
//用大炮工厂制迫击炮
Gun mortar = GunFactory.getGun("Mortar");
mortar.aim();
mortar.shoot();
//用大炮工厂制造出榴弹炮
Gun howitzer = GunFactory.getGun("Howitzer");
howitzer.aim();
howitzer.shoot();
}
}
我们成功造出了大炮,并且效果理想:
迫击炮-瞄准
迫击炮-发射
榴弹炮-瞄准
榴弹炮-射击
现在思考下,我们是否可以把工厂的建造方法,用类似的方法来实现呢,弄一个超级工厂出来:
有两种实现方案,第一种是建造出造工厂的超级工厂,第二种是造出既能造飞机也能造大炮的工厂。如果实现第一种,我们恰好在第二种方法中可以去实现(合二为一)。
现在,我们先来实现第二种,首先定义机械工厂的标准:
//既能造飞机,也能造大炮的工厂,我们简称机械工厂
public interface MachineFactory {
//造飞机
public Plain getPlain(String plainType);
//造大炮
public Gun getGun(String gunType);
}
我们需要改造飞机工厂和大炮工厂,去实现这套标准:
//飞机工厂,实现了机械工厂的造飞机功能,至于造大炮,具体实现交给大炮工厂,PlainFactory.java
public class PlainFactory implements MachineFactory {
//造飞机
public Plain getPlain(String plainType) {
if(plainType==null){
return null;
}
if(plainType.equals("Boeing777")){
return new Boeing777();
}else if(plainType.equals("Apache")){
return new Apache();
}else{
return null;
}
}
public Gun getGun(String gunType) {
return null;
}
}
//大炮工厂,实现了机械工厂中造大炮功能,至于造飞机,具体实现交给飞机工厂,GunFactory.java
public class GunFactory implements MachineFactory{
//根据需要建造大炮
public Gun getGun(String gunType){
if(gunType==null){
return null;
}
if(gunType.equals("Mortar")){
return new Mortar();
}else if(gunType.equals("Howitzer")){
return new Howitzer();
}else{
return null;
}
}
public Plain getPlain(String plainType) {
return null;
}
}
改造完成后,我们发现,此时可以通过一个超级工厂去建造工厂了:
//能建造工厂的超级工厂
public class SuperFactory{
//根据需要建造对应工厂
public static MachineFactory getPlainFactory(String factoryType) {
if(factoryType==null){
return null;
}
if(factoryType.equals("PlainFactory")){
return new PlainFactory();
}else if(factoryType.equals("GunFactory")){
return new GunFactory();
}else{
return null;
}
}
}
我们来检验一下:
//老客户又来了
public class Custormer {
public static void main(String[] args) {
//我们自己的飞机工厂
MachineFactory plainFactory = SuperFactory.getPlainFactory("PlainFactory");
//造出一辆阿帕奇直升机
Plain apache = plainFactory.getPlain("Apache");
apache.fly();
apache.navigation();
//我们自己的大炮工厂
MachineFactory gunFactory = SuperFactory.getPlainFactory("GunFactory");
//造出一台榴弹炮
Gun howitzer = gunFactory.getGun("Howitzer");
howitzer.aim();
howitzer.shoot();
}
}
这就是抽象工厂模型,结果如下:
阿帕奇-飞
阿帕奇-导航
榴弹炮-瞄准
榴弹炮-射击
如果笔者笔述有误,或者有理解错误,还请务必告知。