工廠模式的實現主要分為三種,分别是簡單工廠模式(Simple factory)、工廠方法模式(Factory Method)和抽象工廠模式(Abastract Factory );但是簡單工廠模式不屬于23種GOF設計模式之一。工廠模式在各種開源框架裡使用非常普遍,例如Spring框架大量使用工程模式。下面分别介紹一下這三種實現。
0x01: 簡單工廠模式
簡單工廠模式也被稱為靜态工廠模式;簡單工廠模式可以将産品的使用和生産完全分開,客戶端隻需要知道需要什麼産品,如何來使用産品就可以了,而具體的産品生産任務由具體的工廠類來實現。工廠類根據傳進來的參數生産具體的産品供消費者使用。這種模式使得更加利于擴展,當有新的産品加入時僅僅需要在工廠中加入新産品的構造就可以了。類圖如下
簡單工廠模式的實質是由一個工廠類根據傳入的參數,動态決定應該創建哪一個産品類(這些産品類繼承自一個父類或接口)的實例。該模式中包含的角色及其職責:
抽象産品(IProduct)角色
publicinterfaceIFruit{
/**
*種植水果方法
*/
voidplant();
}
抽象産品(IProduct)角色
//實現種植蘋果
publicclassAppleimplementsIFruit{
publicvoidplant(){
System.out.println("種植蘋果");
}
}
//實現種植橙子
publicclassOrangeimplementsIFruit{
publicvoidplant(){
System.out.println("種植橙子");
}
}
具體産品(Concrete Product)角色
publicclassPlantFruitsFactory{
public staticIFruitplantFruit(StringfruitType){
//這裡使用的if判斷,用switch一樣的道理
if("Apple".equals(fruitType)){
returnnewApple();
}elseif("Orange".equals(fruitType)){
returnnewOrange();
}else{
returnnull;
}
}
}
測試用例
publicclassClientCmd{
publicstaticvoidmain(String[]args){
IFruitfruit=PlantFruitsFactory.plantFruit("Apple");
fruit.plant();
fruit=PlantFruitsFactory.plantFruit("Orange");
fruit.plant();
}
}
0x02: 工廠方法模式
工廠方法(Factory Method)模式的定義是一個創建産品對象的工廠接口,将實際創建工作推遲到子類當中。核心工廠類不再負責産品的創建,這樣核心類成為一個抽象工廠角色,僅是負責具體工廠子類必須實現的接口,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的産品。類圖如下:
抽象産品(Product)角色
//抽象産品類
publicabstractclassIMessage{
//抽象産品方法
publicvoidsend();
}
具體産品(Concrete Product)角色
//繼承抽象類實現産品EmailMessage類
publicclassEmailMessage extendsIMessage{
//實現抽象産品方法
@Overide
publicvoid send(){
System.out.println("send Email Message~~");
}
}
//繼承抽象類實現産品SmsMessage類
publicclassSmsMessage extendsIMessage{
//實現抽象産品方法
@Overide
publicvoid send(){
System.out.println("send Sms Message ~~~ ");
}
}
抽象工廠(Creator)角色
//工廠抽象類
publicabstractclassFactory{
//抽象工廠方法
publicabstractIMessage createMessage();
}
具體工廠(Concrete Creator)角色
//具體工廠類EmailMessageFactory
publicclassEmailMessageFactoryextendsFactory{
@Overide
publicIMessage createMessage(){
System.out.println("生産了一個EmailMessage ");
returnnewEmailMessage();
}
}
//具體工廠類SmsMessageFactory
publicclassSmsMessageFactoryextendsFactory{
@Overide
publicIMessage createMessage(){
System.out.println("生産了一個SmsMessage");
returnnewSmsMessage();
}
}
測試用例
//調用方代碼
publicclassClientCmd{
publicstaticvoidmain(String[]args){
//産生一個Email工廠
Factoryfactory=newEmailMessageFactory();
factory.createMessage().send();
//産生一個短信工廠
factory=newSmsMessageFactory();
orangeFactory.createMessage().send();
}
}
0x03: 抽象工廠模式
抽象工廠模式相對于工廠方法模式來說,就是工廠方法模式是針對一個産品系列的,而抽象工廠模式是針對多個産品系列的,即工廠方法模式是一個産品系列一個工廠類,而抽象工廠模式是多個産品系列一個工廠類。在抽象工廠模式中,客戶端不再負責對象的創建,而是把這個責任丢給了具體的工廠類,客戶端隻負責對對象的調用,從而明确了各個類的職責。并且當一系列相互關聯的産品被設計到一個工廠類裡後,客戶端的調用将會變得非常簡單,而且如果要更換這一系列的産品,則隻需要更換一個工廠類即可。類圖如下
抽象工廠模式中存在四種角色,分别是抽象工廠角色,具體工廠角色,抽象産品角色,具體産品角色。
抽象産品角色
//抽象形狀類
publicabstractclassShape{
publicabstractvoidsayShape();
}
//抽象顔色類
publicabstractclassColor{
publicabstractvoidsayColor();
}
具體産品角色
//矩形類
publicclassRetangleextendsShape{
@Overide
publicvoidsayShape(){
System.out.println("Hi,I'mRetangle!");
}
}
//圓形類
publicclassCircleextendsShape{
@Overide
publicvoidsayShape(){
System.out.println("Hi,I'mCircle!");
}
}
//紅色類
publicclassRedextendsColor{
@Overide
publicvoidsayColor(){
System.out.println("Hi,I'mRed!");
}
}
//白色類
publicclassWhiteextendsColor{
@Overide
publicvoidsayColor(){
System.out.println("Hi,I'mWhite!");
}
}
抽象工廠角色
//抽象工廠類
publicabstractclassShapeFactory{
publicabstractShapecreateShape();
publicabstractColorcreateColor();
}
具體工廠角色
//紅色的圓
publicclassRedCircleFactoryextendsShapeFactory{
@Overide
publicShapecreateShape(){
returnnewCircle();
}
@Overide
publicColorcreateColor(){
returnnewRed();
}
}
//白色的圓
publicclassWhiteCircleFactoryextendsShapeFactory{
@Overide
publicShapecreateShape(){
returnnewCircle();
}
@Overide
publicColorcreateColor(){
returnnewWhite();
}
}
測試用例
publicclassClientCmd{
publicstaticvoidmain(String[]args){
//紅色的圓
ShapeFactoryfactory=newRedCircleFactory();
factory.createShape().sayShape();
factory.createColor().sayShapeColor();
//白色的圓
ShapeFactoryfactory=newWhiteCircleFactory();
factory.createShape().sayShape();
factory.createColor().sayShapeColor();
}
}
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!