天天看点

简单工厂模式+静态工厂+抽象工厂

工厂模式(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();
	}
}
           

这就是抽象工厂模型,结果如下:

阿帕奇-飞
阿帕奇-导航
榴弹炮-瞄准
榴弹炮-射击
           

如果笔者笔述有误,或者有理解错误,还请务必告知。

继续阅读