設計模式 之 抽象工廠

前一篇文章,介紹了工廠方法,並且,探討了下工廠方法的不足之處:

及我們知道,在工廠方法中,每個 Creator,只是創建單一的實例,那對於一次要創建n多不同的類實例的情況呢?
及,如果我們要實現這樣的方法呢?:
using System;
using System.Collections.Generic;
using System.Text;

namespace 工廠方法
{
    public interface ICreator<T> where T : IDomain
    {
        ISpeciality<T> CreaterSpeciality( );
        //這裏帶上其他的類的創建方法
    }
}

抽象工廠,爲我們很好的解決了這個問題。

如在一個農場中,會種植水果和蔬菜。而蔬菜和水果的種類,又因地域的不同而不同,如:南方的農民種植的水果爲荔枝,蔬菜爲苦瓜,北方的農民種植的水果是紅棗,蔬菜是大白菜。一個農場的農民,農場主不可能要求他的工人在會種植一樣東西,需要都能夠種植。用程序來解釋,如下:

農民接口:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public interface 農民接口
    {
        蔬菜接口 種植蔬菜();

        水果接口 種植水果();

    }
}

 

水果接口:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    /// <summary>
    /// 水果的接口
    /// </summary>
    public interface 水果接口
    {
        /// <summary>
        /// 水果的味道
        /// </summary>
        /// <returns></returns>
        string 味道();
        /// <summary>
        /// 水果生長週期
        /// </summary>
        /// <returns></returns>
        int 水果生長週期();

        /// <summary>
        /// 水果生長區域
        /// </summary>
        /// <returns></returns>
        string 生長區域();
        
    }
}

蔬菜接口:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    /// <summary>
    /// 蔬菜接口
    /// </summary>
   public interface 蔬菜接口
    {
       /// <summary>
       /// 蔬菜生長區域
       /// </summary>
       /// <returns></returns>
       string 生長區域();

       /// <summary>
       /// 一棵種子是否只長一個果實
       /// </summary>
       /// <returns></returns>
       bool 一棵種子是否只長一個果實();
    }
}

各種水果類:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    /// <summary>
    /// 荔枝類 南方生產的水果
    /// </summary>
    public class 荔枝 : 水果接口
    {
        public string 味道()
        {
            return "荔枝非常的甜";
        }

        public int 水果生長週期()
        {
            return 1;
        }
        public string 生長區域()
        {
            return "南方";
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public class 紅棗 : 水果接口
    {
        public string 味道()
        {
            return "紅棗有點甜";
        }

        public int 水果生長週期()
        {
            return 1;
        }
        public string 生長區域()
        {
            return "北方";
        }
    }
}

各種蔬菜類:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public class 大白菜 : 蔬菜接口
    {
        public string 生長區域()
        {
            return "北方";
        }

        public bool 一棵種子是否只長一個果實()
        {
            return true;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public class 苦瓜 : 蔬菜接口
    {
      public  string 生長區域()
        {
            return "南方";
        }

        public bool 一棵種子是否只長一個果實()
        {
            return false;
        }
    }
}

農民類:

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public class 南方農民 : 農民接口
    {
        public 蔬菜接口 種植蔬菜()
        {
            return new 苦瓜();
        }

        public 水果接口 種植水果()
        {
            return new 荔枝();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace 抽象工廠
{
    public class 北方農民 : 農民接口
    {
        public 蔬菜接口 種植蔬菜()
        {
            return new 大白菜();
        }

        public 水果接口 種植水果()
        {
            return new 紅棗();
        }
    }
}

使用的時候:

  private void button1_Click(object sender, EventArgs e)
        {
            農民接口 一個農民 = new 南方農民();
            水果接口 水果 = 一個農民.種植水果();
            蔬菜接口 蔬菜 = 一個農民.種植蔬菜();
        }

這樣,南方的農民就可以同時種植南方的水果和南方的蔬菜了,也就解決了一個農民只能夠種植一種東西的情況,也就是解決了工廠方法的問題。

 

抽象工廠 和 建造者buileder的不同:

首先,抽象工廠返回的是一個完完全全的產品對象,客戶端 可以根據這些產品對象,再去組裝出更加複雜的產品對象。

而建造者,返回的不是一個完整的產品對象,客戶端需要自己在去把產品的各個部件在組裝起來。

如果兩個模式結合起來用,情況可以這樣:

如在一個遊戲中,如:西山居 開發的 劍俠情緣 來說,一張地圖上,需要建立房子,道路,路標,廣告牌等等,

一張地圖,需要創建這些東西,而這些房子呀什麼的,又有不同的風格,建造者+抽象工廠,就可以能夠滿足這個地圖的創建(呵呵,對於該遊戲到底是怎麼弄的,我是不知道,自己亂想的)

上面的程序,用的中文表示,呵呵,一是測試vs裏面能夠用中文不,二是這樣看起來容易點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章