日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

抽象工廠模式(Abstract Factory Pattern)

 漂在北方的狼 2007-03-28

一、 抽象工廠(Abstract Factory)模式

抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。

為了方便引進(jìn)抽象工廠模式,引進(jìn)一個(gè)新概念:產(chǎn)品族(Product Family)。所謂產(chǎn)品族,是指位于不同產(chǎn)品等級結(jié)構(gòu),功能相關(guān)聯(lián)的產(chǎn)品組成的家族。如圖:

 

圖中一共有四個(gè)產(chǎn)品族,分布于三個(gè)不同的產(chǎn)品等級結(jié)構(gòu)中。只要指明一個(gè)產(chǎn)品所處的產(chǎn)品族以及它所屬的等級結(jié)構(gòu),就可以唯一的確定這個(gè)產(chǎn)品。

引進(jìn)抽象工廠模式

所謂的抽象工廠是指一個(gè)工廠等級結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級結(jié)構(gòu)的一個(gè)產(chǎn)品族中的所有對象。如果用圖來描述的話,如下圖:

 

二、 Abstract Factory模式的結(jié)構(gòu):

 

圖中描述的東西用產(chǎn)品族描述如下:

 


抽象工廠(Abstract Factory)角色:擔(dān)任這個(gè)角色的是工廠方法模式的核心,它是與應(yīng)用系統(tǒng)商業(yè)邏輯無關(guān)的。

具體工廠(Concrete Factory)角色:這個(gè)角色直接在客戶端的調(diào)用下創(chuàng)建產(chǎn)品的實(shí)例。這個(gè)角色含有選擇合適的產(chǎn)品對象的邏輯,而這個(gè)邏輯是與應(yīng)用系統(tǒng)的商業(yè)邏輯緊密相關(guān)的。

抽象產(chǎn)品(Abstract Product)角色:擔(dān)任這個(gè)角色的類是工廠方法模式所創(chuàng)建的對象的父類,或它們共同擁有的接口。

具體產(chǎn)品(Concrete Product)角色:抽象工廠模式所創(chuàng)建的任何產(chǎn)品對象都是某一個(gè)具體產(chǎn)品類的實(shí)例。這是客戶端最終需要的東西,其內(nèi)部一定充滿了應(yīng)用系統(tǒng)的商業(yè)邏輯。


三、 程序舉例:

該程序演示了抽象工廠的結(jié)構(gòu),本身不具有任何實(shí)際價(jià)值。

 

// Abstract Factory pattern -- Structural example  
using System;

// "AbstractFactory"
abstract class AbstractFactory
{
  
// Methods
  abstract public AbstractProductA CreateProductA();
  
abstract public AbstractProductB CreateProductB();
}


// "ConcreteFactory1"
class ConcreteFactory1 : AbstractFactory
{
  
// Methods
  override public AbstractProductA CreateProductA()
  
{
    
return new ProductA1();
  }

  
override public AbstractProductB CreateProductB()
  
{
    
return new ProductB1();
  }

}


// "ConcreteFactory2"
class ConcreteFactory2 : AbstractFactory
{
  
// Methods
  override public AbstractProductA CreateProductA()
  
{
    
return new ProductA2();
  }


  
override public AbstractProductB CreateProductB()
  
{
    
return new ProductB2();
  }

}


// "AbstractProductA"
abstract class AbstractProductA
{
}


// "AbstractProductB"
abstract class AbstractProductB
{
  
// Methods
  abstract public void Interact( AbstractProductA a );
}


// "ProductA1"
class ProductA1 : AbstractProductA
{
}


// "ProductB1"
class ProductB1 : AbstractProductB
{
  
// Methods
  override public void Interact( AbstractProductA a )
  
{
    Console.WriteLine( 
this + " interacts with " + a );
  }

}


// "ProductA2"
class ProductA2 : AbstractProductA
{
}


// "ProductB2"
class ProductB2 : AbstractProductB
{
  
// Methods
  override public void Interact( AbstractProductA a )
  
{
    Console.WriteLine( 
this + " interacts with " + a );
  }

}


// "Client" - the interaction environment of the products
class Environment
{
  
// Fields
  private AbstractProductA AbstractProductA;
  
private AbstractProductB AbstractProductB;

  
// Constructors
  public Environment( AbstractFactory factory )
  
{
    AbstractProductB 
= factory.CreateProductB();
    AbstractProductA 
= factory.CreateProductA();
  }

 
  
// Methods
  public void Run()
  
{
    AbstractProductB.Interact( AbstractProductA );
  }

}


/// 
/// ClientApp test environment
/// 

class ClientApp
{
  
public static void Main(string[] args)
  
{
    AbstractFactory factory1 
= new ConcreteFactory1();
    Environment e1 
= new Environment( factory1 );
    e1.Run();

    AbstractFactory factory2 
= new ConcreteFactory2();
    Environment e2 
= new Environment( factory2 );
    e2.Run();
  }

}

 

 


四、 在什么情形下使用抽象工廠模式:

在以下情況下應(yīng)當(dāng)考慮使用抽象工廠模式:

  • 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對于所有形態(tài)的工廠模式都是重要的。
  • 這個(gè)系統(tǒng)有多于一個(gè)的產(chǎn)品族,而系統(tǒng)只消費(fèi)其中某一產(chǎn)品族。
  • 同屬于同一個(gè)產(chǎn)品族的產(chǎn)品是在一起使用的,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來。
  • 系統(tǒng)提供一個(gè)產(chǎn)品類的庫,所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶端不依賴于實(shí)現(xiàn)。

五、 抽象工廠的起源

據(jù)說最早的應(yīng)用是用來創(chuàng)建在不同操作系統(tǒng)的視窗環(huán)境下都能夠運(yùn)行的系統(tǒng)。比如在Windows與Unix系統(tǒng)下都有視窗環(huán)境的構(gòu)件,在每一個(gè)操作系 統(tǒng)中,都有一個(gè)視窗構(gòu)件組成的構(gòu)件家族。我們可以通過一個(gè)抽象角色給出功能描述,而由具體子類給出不同操作系統(tǒng)下的具體實(shí)現(xiàn),如圖:

 

可以發(fā)現(xiàn)上面產(chǎn)品類圖有兩個(gè)產(chǎn)品等級結(jié)構(gòu),分別是Button與Text;同時(shí)有兩個(gè)產(chǎn)品族:Unix產(chǎn)品族與Windows產(chǎn)品族。

 

系統(tǒng)對產(chǎn)品對象的創(chuàng)建要求由一個(gè)工廠的等級結(jié)構(gòu)滿足。其中有兩個(gè)具體工廠角色,即UnixFactory和WinFactory。UnixFactory對象負(fù)責(zé)創(chuàng)建Unix產(chǎn)品族中的產(chǎn)品,而WinFactory負(fù)責(zé)創(chuàng)建Windows產(chǎn)品族中的產(chǎn)品。

 

顯然一個(gè)系統(tǒng)只能夠在某一個(gè)操作系統(tǒng)的視窗環(huán)境下運(yùn)行,而不能同時(shí)在不同的操作系統(tǒng)上運(yùn)行。所以,系統(tǒng)實(shí)際上只能消費(fèi)屬于同一個(gè)產(chǎn)品族的產(chǎn)品。

在現(xiàn)代的應(yīng)用中,抽象工廠模式的使用范圍已經(jīng)大大擴(kuò)大了,不再要求系統(tǒng)只能消費(fèi)某一個(gè)產(chǎn)品族了。


六、 Abstract Factory模式在實(shí)際系統(tǒng)中的實(shí)現(xiàn)

Herbivore:草食動(dòng)物
Carnivore:食肉動(dòng)物
Bison:[‘baisn],美洲或歐洲的野牛

下面實(shí)際代碼演示了一個(gè)電腦游戲中創(chuàng)建不同動(dòng)物的抽象工廠。盡管在不同大陸下動(dòng)物物種是不一樣的,但動(dòng)物間的關(guān)系仍然保留了下來。

 

// Abstract Factory pattern -- Real World example  
using System;

// "AbstractFactory"
abstract class ContinentFactory
{
  
// Methods
  abstract public Herbivore CreateHerbivore();
  
abstract public Carnivore CreateCarnivore();
}


// "ConcreteFactory1"
class AfricaFactory : ContinentFactory
{
  
// Methods
  override public Herbivore CreateHerbivore()
  
return new Wildebeest(); }

  
override public Carnivore CreateCarnivore()
  
return new Lion(); }
}


// "ConcreteFactory2"
class AmericaFactory : ContinentFactory
{
  
// Methods
  override public Herbivore CreateHerbivore()
  
return new Bison(); }

  
override public Carnivore CreateCarnivore()
  
return new Wolf(); }
}


// "AbstractProductA"
abstract class Herbivore
{
}


// "AbstractProductB"
abstract class Carnivore
{
  
// Methods
  abstract public void Eat( Herbivore h );
}


// "ProductA1"
class Wildebeest : Herbivore
{
}


// "ProductB1"
class Lion : Carnivore
{
  
// Methods
  override public void Eat( Herbivore h )
  
{
    
// eat wildebeest
    Console.WriteLine( this + " eats " + h );
  }

}


// "ProductA2"
class Bison : Herbivore
{
}


// "ProductB2"
class Wolf : Carnivore
{
  
// Methods
  override public void Eat( Herbivore h )
  
{
    
// Eat bison
    Console.WriteLine( this + " eats " + h );
  }

}


// "Client"
class AnimalWorld
{
  
// Fields
  private Herbivore herbivore;
  
private Carnivore carnivore;

  
// Constructors
  public AnimalWorld( ContinentFactory factory )
  
{
    carnivore 
= factory.CreateCarnivore();
    herbivore 
= factory.CreateHerbivore();
  }


  
// Methods
  public void RunFoodChain()
  
{ carnivore.Eat(herbivore); }
}


/// 
///  GameApp test class
/// 

class GameApp
{
  
public static void Main( string[] args )
  
{
    
// Create and run the Africa animal world
    ContinentFactory africa = new AfricaFactory();
    AnimalWorld world 
= new AnimalWorld( africa );
    world.RunFoodChain();

    
// Create and run the America animal world
    ContinentFactory america = new AmericaFactory();
    world 
= new AnimalWorld( america );
    world.RunFoodChain();
  }

}

 

抽象工廠的另外一個(gè)例子:

如何設(shè)計(jì)抽象類工廠留作思考。


七、 "開放-封閉"原則

"開放-封閉"原則要求系統(tǒng)對擴(kuò)展開放,對修改封閉。通過擴(kuò)展達(dá)到增強(qiáng)其功能的目的。對于涉及到多個(gè)產(chǎn)品族與多個(gè)產(chǎn)品等級結(jié)構(gòu)的系統(tǒng),其功能增強(qiáng)包括兩方面:

增加產(chǎn)品族:Abstract Factory很好的支持了"開放-封閉"原則。

增加新產(chǎn)品的等級結(jié)構(gòu):需要修改所有的工廠角色,沒有很好支持"開放-封閉"原則。

綜合起來,抽象工廠模式以一種傾斜的方式支持增加新的產(chǎn)品,它為新產(chǎn)品族的增加提供方便,而不能為新的產(chǎn)品等級結(jié)構(gòu)的增加提供這樣的方便。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多