工廠模式是我們最常用的實例化對象模式了,是用工廠方法代替new操作的一種模式。工廠模式在Java程序系統可以說是隨處可見。因爲工廠模式就相當於創建實例對象的new,我們經常要根據類Class生成實例對象,如A a=new A() 工廠模式也是用來創建實例對象的,所以以後new時就要多個心眼,是否可以考慮使用工廠模式,雖然這樣做,可能多做一些工作,但會給你係統帶來更大的可擴展性和儘量少的修改量。
一、簡單工廠模式(Simple Factory)
建立一個工廠(一個函數或一個類方法)來製造新的對象。
簡單工廠模式的組成:
1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯,用來創建產品
2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。
3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在Java中由一個具體類實現。
產品類:
abstract class Product{
public Product(){
}
}
public class Product_1 extends Product {
public Product_1() {
System.out.println("製造-->產品1");
}
}
public class Product_2 extends Product{
public Product_2(){
System.out.println("製造-->產品2");
}
}
工廠類:
public class Factory {
public Product createProduct(int type) {
switch (type) {
case 1:
return new Product_1();
case 2:
return new Product_2();
default:
break;
}
return null;
}
}
客戶類:
Public class Customer{
public static void main(String[] args){
Factory factory = new Factory();
Product product_1 = factory.create(1);
Product product_2 = factory.create(2);
}
}
簡單工廠模式又稱靜態工廠方法模式。它存在的目的很簡單:定義一個用於創建對象的接口。
從開閉原則(對擴展開放;對修改封閉)上來分析:
對產品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因爲每增加一種新型車,都要在工廠類中增加相應的創建業務邏輯(createProduct(int type)方法需要新增case),這顯然是違背開閉原則的。
二、工廠方法模式(Factory Method)
工廠方法模式去掉了簡單工廠模式中工廠方法的靜態屬性,使得它可以被子類繼承。這樣在簡單工廠模式裏集中在工廠方法上的壓力可以由工廠方法模式裏不同的工廠子類來分擔。
工廠方法模式組成:
一個抽象產品類:可以派生出多個具體產品類。
一個抽象工廠類:可以派生出多個具體工廠類。
每個具體工廠類只能創建一個具體產品類的實例。
產品類:
abstract class Product{
public Product(){
}
}
public class Product_1 extends Product {
public Product_1() {
System.out.println("製造-->產品1");
}
}
public class Product_2 extends Product{
public Product_2(){
System.out.println("製造-->產品2");
}
}
工廠類:
public interface Factory {
Product createProduct();
}
public class Product_1Factory() implements Factory{
@Override
public Product_1 createProduct() {
return new Product_1();
}
}
public class Product_2Factory() implements Factory{
@Override
public Product_2 createProduct() {
return new Product_2();
}
}
客戶類:
public class Customer(){
public static void main(String[] args){
Product_1Factory product_1Factory = new Product_1Factory();
Product_1 product_1 = product_1Factory.createProduct();
Product_2Factory product_2Factory = new Product_2Factory();
Product_2 product_2 = product_2Factory.createProduct();
}
}
當有新的產品產生時,只要按照抽象產品角色、抽象工廠角色提供的合同來生成,那麼就可以被客戶使用,而不必去修改任何已有 的代碼。可以看出工廠角色的結構也是符合開閉原則的!
工廠方法模式彷彿已經很完美的對對象的創建進行了包裝,使得客戶程序中僅僅處理抽象產品角色提供的接口,但使得對象的數量成倍增長。當產品種類非常多時,會出現大量的與之對應的工廠對象,這不是我們所希望的。
三、抽象工廠模式(Abstract Factory)
當每個抽象產品都有多於一個的具體子類的時候,工廠角色怎麼知道實例化哪一個子類呢?比如每個抽象產品角色都有兩個具體產品。抽象工廠模式提供兩個具體工廠角色,分別對應於這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的實例化。每一個具體工廠類只負責創建抽象產品的某一個具體子類的實例。
每一個模式都是針對一定問題的解決方案,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是多個產品等級結構。
抽象產品模式組成:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類可以創建多個具體產品類的實例。
產品類:
//第一類組件
public abstract class Component_1{ }
//第一類組件A型號
public class Component_1A extends Component {
public Component_1A() {
System.out.println("製造-->第一類組件A型號");
}
}
//第一類組件B型號
public class Component_1B extends Component{
public Component_1B(){
System.out.println("製造-->第一類組件B型號");
}
}
//第二類組件
public abstract Component_2{ }
//第二類組件A型號
public class Component_2A extends Component {
public Component_2A() {
System.out.println("製造-->第二類組件A型號");
}
}
//第二類組件B型號
public class Component_2B extends Component{
public Component_2B(){
System.out.println("製造-->第二類組件B型號");
}
}
工廠類:
//創建工廠的接口
public interface Factory {
//創建第一類組件
Component_1 createComponent_1();
//創建第二類組件
Component_2 createComponent_2();
}
//爲產品一生產組件,由第一類組件A和第二類組件B構成
public class Product_1Factory() implements Factory{
@Override
public Component_1 createComponent_1() {
return new Component_1A();
}
public Component_2 createComponent_2() {
return new Component_2B();
}
}
//爲產品二生產組件,由第一類組件B和第二類組件B構成
public class Product_2Factory() implements Factory{
@Override
public Component_1 createComponent_1() {
return new Component_1B();
}
public Component_2 createComponent_2() {
return new Component_2B();
}
}
客戶類:
public class Customer{
public static void main(String[] args){
Product_1Factory product_1 = new Product_1Factory();
product_1.createComponent_1();
product_1.createComponent_2();
Product_2Factory product_2 = new Product_1Factory();
product_2.createComponent_1();
product_2.createComponent_2();
}
}