本文從一個簡單示例的需求不斷衍化過程,來分析理解簡單工廠,工廠方法,抽象工廠模式。
首先看一下初始示例
public interface Car {
public void drive();
}
public class BenzCar implements Car {
@Override
public void drive() {
System.out.println("Benz Car drived on the way!");
}
}
public class BmwCar implements Car{
@Override
public void drive() {
System.out.println("Bmw car drived on the way!");
}
}
public class PorscheCar implements Car {
@Override
public void drive() {
System.out.println("Porsche car drived on the way!");
}
}
public class Client {
public static void main(String[] args){
Car car;
car = new BenzCar();
car.drive();
car = new BmwCar();
car.drive();
}
}
客戶端與具體的Car實現類耦合,我們想到優化的第一步是把獲得汽車的工作轉移到工廠類,使用簡單工廠把生產Car的邏輯做一層封裝實現解耦,於是有了下面的代碼
public class SimpleCarFactory {
public Car createCar(String car){
Car newCar = null;
if("Benz".equals(car)){
newCar = new BenzCar();
}else if("Bmw".equals(car)){
newCar = new BmwCar();
}else if("Porsche".equals(car)){
newCar = new PorscheCar();
}else {
throw new RuntimeException("Car brand Invalid!");
}
return newCar;
}
}
public class Client {
public static void main(String[] args){
Car car = new SimpleCarFactory().createCar("Benz");
if(car != null){
car.drive();
}
}
}
Client類看起來清晰了很多,需要汽車直接從工廠獲取就可以,但隨後我們想到這樣一個問題,隨着以後car品牌的增多,我們需要不斷在SimpleCarFactory中增加if…else…代碼,違背了OO的對擴展開放,對修改關閉的原則,於是我們想到了工廠方法,對工廠的變化實現解耦。
public interface CarFactory {
public Car createCar() throws Exception;
}
public class BenzCarFactory implements CarFactory {
@Override
public Car createCar() throws Exception {
return new BenzCar();
}
}
public class BmwCarFactory implements CarFactory {
@Override
public Car createCar() throws Exception {
return new BmwCar();
}
}
public class PorscheCarFactory implements CarFactory {
@Override
public Car createCar() throws Exception {
return new PorscheCar();
}
}
public class VolvoCarFactory implements CarFactory{
@Override
public Car createCar() throws Exception {
return new VolvoCar();
}
}
public class Client {
public static void main(String[] args) throws Exception{
CarFactory carFactory = null;
Car car = null;
carFactory = new BenzCarFactory();
car = carFactory.createCar();
car.drive();
carFactory = new VolvoCarFactory();
car = carFactory.createCar();
car.drive();
}
}
工廠方法實現後,我們增加了VolvoCar,只需要增加VolvoCarFactory的工廠生產VolvoCar,就可以在客戶端直接調用,非常方便。
But,隨着業務的日漸複雜,所有的汽車品牌都發展出了不同功能的汽車,如跑車,商務車,越野車,客戶如果需要Benz的跑車,這個時候工廠該怎麼處理呢?
分析需求可以理解:車的類型基本變動不大,主要是品牌的不斷增加,比如之後會有大衆,奧迪等品牌的加入。
因此,可以考慮在工廠方法的基礎上,把工廠進行一層抽象,於是有了下面的抽象工廠的實現。
public class BenzBusinessCar extends BenzCar {
@Override
public void drive() {
System.out.println("Benz Business Car drived on the way!");
}
}
public class BenzSportCar extends BenzCar {
@Override
public void drive() {
System.out.println("Benz Sport Car drived on the way!");
}
}
public class BenzSUVCar extends BenzCar {
@Override
public void drive() {
System.out.println("Benz SUV Car drived on the way!");
}
}
public class BmwBusinessCar extends BmwCar {
@Override
public void drive() {
System.out.println("Bmw Business Car drived on the way!");
}
}
public class BmwSportCar extends BmwCar {
@Override
public void drive() {
System.out.println("Bmw Sport car drived on the way!");
}
}
public class BmwSUVCar extends BmwCar {
@Override
public void drive() {
System.out.println("Bmw SUV car drived on the way!");
}
}
public class PorscheBusinessCar extends PorscheCar {
@Override
public void drive() {
System.out.println("Porsche Business car drived on the way!");
}
}
public class PorscheSportCar extends PorscheCar {
@Override
public void drive() {
System.out.println("Porsche Sport car drived on the way!");
}
}
public class PorscheSUVCar extends PorscheCar {
@Override
public void drive() {
System.out.println("Porsche SUV car drived on the way!");
}
}
public interface CarFactory {
Car createBusinessCar();
Car createSUVCar();
Car createSportCar();
}
public class BenzCarFactory implements CarFactory{
@Override
public BenzCar createBusinessCar() {
return new BenzBusinessCar();
}
@Override
public BenzCar createSUVCar() {
return new BenzSUVCar();
}
@Override
public BenzCar createSportCar() {
return new BenzSportCar();
}
}
public class BmwCarFactory implements CarFactory {
@Override
public BmwCar createBusinessCar() {
return new BmwBusinessCar();
}
@Override
public BmwCar createSUVCar() {
return new BmwSUVCar();
}
@Override
public BmwCar createSportCar() {
return new BmwSportCar();
}
}
public class PorscheCarFactory implements CarFactory {
@Override
public PorscheCar createBusinessCar() {
return new PorscheBusinessCar();
}
@Override
public PorscheCar createSUVCar() {
return new PorscheSUVCar();
}
@Override
public PorscheCar createSportCar() {
return new PorscheSportCar();
}
}
public class Client {
public static void main(String[] args){
createCarAndDrive(new BenzCarFactory());
createCarAndDrive(new PorscheCarFactory());
}
public static void createCarAndDrive(CarFactory carFactory){
Car businessCar = carFactory.createBusinessCar();
businessCar.drive();
Car sportCar = carFactory.createSportCar();
sportCar.drive();
Car suvCar = carFactory.createSUVCar();
suvCar.drive();
}
}
這樣客戶獲得一輛想要的車就很方便,只要確定哪個品牌,獲得對應品牌的工廠,然後從工廠裏獲得想要的類型的車就可以了。
似乎一切都很順利
但隨着業務的不斷複雜,需要增加幾種車的類型呢,比如說增加輕便的兩座車,長10m的貴賓車,對於目前抽象工廠,貌似改動會非常大,這種情況有如何方便地擴展呢?
留做思考,後續解答!