設計模式之工廠模式

工廠模式主要是爲建立對象提供過渡接口,以便將建立對象的具體過程屏蔽隔離起來,達到提升靈活性的目的。 
工廠模式能夠分爲三類: java

1)簡單工廠模式(Simple Factory) 
2)工廠方法模式(Factory Method) 
3)抽象工廠模式(Abstract Factory) 編程

 這三種模式從上到下逐步抽象,而且更具通常性。 設計模式

GOF在《設計模式》一書中將工廠模式分爲兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看爲工廠方法模式的一種特例,二者歸爲一類。ide

(1)簡單工廠模式spa

背景:一個用戶要生產不一樣類型的車,如寶馬、奧迪、奔馳等,用戶不用在本身的類中直接new,而是經過簡單的工廠進行生產,可是成產的車輛強依賴於用戶的傳參需求。類圖以下設計

 

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$
 */
public class Car {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class Audi extends Car {
    public Audi() {
        System.out.println("Product AudiBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

import com.sun.tools.doclets.internal.toolkit.util.SourceToHTMLConverter;

/**
 * @author admin
 * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class Benz extends Car {
    public Benz() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class Bmw extends Car {
    public Bmw() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;


/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class CarFactory {
    public static Car createCar(String type){
        if (type.equals("AudiBusiness")){
            return new Audi();
        }else if (type.equals("BenzBusiness")){
            return new Benz();
        }else if (type.equals("BmwBusiness")){
            return new Bmw();
        }
        return null;
    }

}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        //生產一個寶馬
        Car car = CarFactory.createCar("BmwBusiness");
        if (car == null) {
            System.out.println("Procuct BmwBusiness failed!");
        }
        //生產一個奧迪
        Car car1 = CarFactory.createCar("AudiBusiness");
        if (car1 == null) {
            System.out.println("Product AudiBusiness failed!");
        }
        //生產一個奔馳
        Car car2 = CarFactory.createCar("BenzBusiness");
        if (car2 == null) {
            System.out.println("Product BenzBusiness failed!");
        }
        //生產一個大衆
        Car car3 = CarFactory.createCar("dazhong");
        if (car3 == null) {
            System.out.println("Product 大衆 failed!");
        }

    }
}

運行結果:code

Product BmwBusiness!
Product AudiBusiness!
Product BenzBusiness!
Product 大衆 failed!

 

 

(2)工廠模式對象

對於簡單的工廠強依賴於用戶輸入,並且當增長了一個新的車輛種類時,對於工廠須要進行修改容易破壞原來的代碼邏輯,不符合開閉原則。以下是工廠模式blog

每一種車型都已一種對應的工廠,當新增車型時只用擴展,不用修改就可以完成新的車型工廠生產。接口

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$
 */
public class Car {
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class Audi extends Car {
    public Audi() {
        System.out.println("Product AudiBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class Benz extends Car {
    public Benz() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class Bmw extends Car {
    public Bmw() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;


/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public interface CarFactory {
    public Car createCar();
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午1:35 admin Exp $$
 */
public class AudiFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Audi();
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$
 */
public class BenzFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benz();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$
 */
public class BmwFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Bmw();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        //生產一個寶馬
        CarFactory carFactory = new BmwFactory();
        Car car = carFactory.createCar();
        if (car == null) {
            System.out.println("Procuct BmwBusiness failed!");
        }
        //生產一個奧迪
        carFactory = new AudiFactory();
        Car car1 = carFactory.createCar();
        if (car1 == null) {
            System.out.println("Product AudiBusiness failed!");
        }
        //生產一個奔馳
        carFactory = new BenzFactory();
        Car car2 = carFactory.createCar();
        if (car2 == null) {
            System.out.println("Product BenzBusiness failed!");
        }
    }
}

運行結果:

Product BmwBusiness!
Product AudiBusiness!
Product BenzBusiness!

(3)抽象工廠模式

抽象工廠使用的時候主要是業務比較複雜的時候纔會考慮,好比當車的種類已經不單單是一個維度了,除了車的品牌,還要涉及到車的類型,如跑車、商務車等。此時車也要拆分到多個維度、跑車,商務車等。

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BusinessCar.java, v 0.1 2015-10-18 下午2:00 admin Exp $$
 */
public class BusinessCar {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id SportsCar.java, v 0.1 2015-10-18 下午2:01 admin Exp $$
 */
public class SportsCar {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class AudiBusiness extends BusinessCar {
    public AudiBusiness() {
        System.out.println("Product AudiBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzBusiness.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class BenzBusiness extends BusinessCar {
    public BenzBusiness() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwBusiness.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class BmwBusiness extends BusinessCar {
    public BmwBusiness() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class AudiSports extends SportsCar {
    public AudiSports() {
        System.out.println("Product AudiSports!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzSports.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class BenzSports extends SportsCar {
    public BenzSports() {
        super();
        System.out.println("Product BenzSports!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwSports.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class BmwSports extends SportsCar {
    public BmwSports() {
        super();
        System.out.println("Product BmwSports!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public interface CarFactory {

    public SportsCar createSportsCar();

    public BusinessCar createBusinessCar();
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午2:15 admin Exp $$
 */
public class AudiFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new AudiSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new AudiBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午2:17 admin Exp $$
 */
public class BenzFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new BenzSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new BenzBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午2:18 admin Exp $$
 */
public class BmwFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new BmwSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new BmwBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        /**生產寶馬*/
        CarFactory carFactory = new BmwFactory();
        //跑車
        SportsCar sportsCar = carFactory.createSportsCar();
        //商務車
        BusinessCar businessCar = carFactory.createBusinessCar();

        /**生產奧迪*/
        carFactory = new AudiFactory();
        //跑車
        sportsCar = carFactory.createSportsCar();
        //商務車
        businessCar = carFactory.createBusinessCar();

        /**生產一個奔馳*/
        carFactory = new BmwFactory();
        //跑車
        sportsCar = carFactory.createSportsCar();
        //商務車
        businessCar = carFactory.createBusinessCar();

    }
}

1.一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節,這對於全部形態的工廠模式都是重要的。

2.這個系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。

3.同屬於同一個產品族的產品是在一塊兒使用的,這一約束必須在系統的設計中體現出來。

4.系統提供一個產品類的庫,全部的產品以一樣的接口出現,從而使客戶端不依賴於實現。

分離接口和實現

客戶端使用抽象工廠來建立須要的對象,而客戶端根本就不知道具體的實現是誰,客戶端只是面向產品的接口編程而已。也就是說,客戶端從具體的產品實現中解耦。

相關文章
相關標籤/搜索