1. 程式人生 > >【設計模式】——抽象工廠模式

【設計模式】——抽象工廠模式

【抽象工廠模式】

抽象工廠模式是圍繞一個超級工廠建立其他工廠,該超級工廠又稱為其他工廠的工廠。這種型別的設計模式屬於建立型模型,它提供了一種建立物件的最佳方式

在抽象工廠模式中,介面是負責建立一個相關物件的工廠,不需要顯式的指定他們的類。每個生成的工廠都能按照工廠模式提供物件

【介紹】

  • 主要解決:介面選擇問題

  • 如何解決:在一個產品族裡面,定義多個產品

  • 關鍵程式碼:在一個工廠裡聚合多爾袞同類產品

  • 優點:1、便於交換產品系列。2、讓具體的建立例項過程和客戶端分離

  • 缺點:產品族拓展困難,要增加一個系列的某一產品,既要在抽象的creator裡面增加程式碼,又要在具體的例項裡面增加程式碼

  • 注意事項:產品族難擴充套件,產品等級易擴充套件

【實現】

步驟一:使用者類

class User

    {

        private int _id;

        public int ID

        {

            get { return _id; }

            set { _id = value; }

        }

        private int _name;

        public int Name

        {

            get { return _name; }

            set { _name = value; }

        }

    }

    class Department

    {

        private int _id;

        public int ID

        {

            get { return _id; }

            set { _id = value; }

        }



        private string _deptName;

        public string DeptName

        {

            get { return _deptName; }

            set { _deptName = value; }

        }

    }

步驟二:介面類

//IUser介面

    interface IUser

    {

        void Insert(User user);

        User GetUser(int id);

    }

    //IDepartment介面,用於客戶端訪問,解除與具體資料庫訪問的耦合

    interface IDepartment

    {

        void Insert(Department department);

        Department GetDepartment(int id);

    }

步驟三:抽象產品類

 class SqlserverDepartment : IDepartment

    {

        public void  Insert(Department department)

        {

            Console.WriteLine("在SQL中user表中增加一條新紀錄");

        }

        public Department GetDepartment(int id)

        {

            Console.WriteLine("在SQL根據ID得到user表一條紀錄");

            return null;

        }

    }

   

    class SqlserverUser : IUser

    {

        public void Insert(User user)

        {

            Console.WriteLine("給ACCess給user表新增一條新紀錄");

        }

        public User GetUser(int id)

        {

            Console.WriteLine("根據ID得到user表一條紀錄");

            return null;

        }

    }

    //AccessUser類,用於訪問Access的user

    class AccessDepartment:IDepartment

    {

        public void Insert(Department department)

        {

            Console.WriteLine("給ACCess給user表新增一條新紀錄");

        }

        public Department GetDepartment (int id)

        {

            Console.WriteLine("根據ID得到user表一條紀錄");

            return null;

        }

    }

    class AccessUser : IUser

    {

        public void Insert(User user)

        {

            Console.WriteLine("給ACCess給user表新增一條新紀錄");

        }

        public User GetUser(int id)

        {

            Console.WriteLine("根據ID得到user表一條紀錄");

            return null;

        }

    }

步驟四:抽象工廠介面

i

nterface IFactory

    {

        IUser CreateUser();

        IDepartment CreateDepartment();

    }



步驟五:實現產品

class SqlserverFactory:IFactory

    {

        public IUser CreateUser()

        {

            return new SqlserverUser ();

        }

        public IDepartment CreateDepartment()

        {

            return new SqlserverDepartment();

        }

    }

    //accessFacrtory類,實現IFactory介面,例項化Accessuser

    class AccessFactory:IFactory

    {

        public IUser CreateUser()

        {

            return new AccessUser();

        }

        public IDepartment CreateDepartment()

        {

            return new AccessDepartment();

        }



    }

步驟六:客戶端程式碼

static void Main(string[] args)

        {

            User user = new User();

            IFactory factory = new SqlserverFactory();

            Department dept = new Department();

            IUser iu = factory.CreateUser();

            iu.Insert(user);

            iu.GetUser(1);

            IDepartment id = factory.CreateDepartment();//此時已與具體的資料庫訪問解除了依賴

            id.Insert(dept);

            id.GetDepartment(1);



            Console.Read();

        }

【總結】

反射的格式:Assembly.Load("程式集名稱").CreateInstance("名稱空間.類名稱")

將程式由編譯時轉為執行時,其中的字串是可以寫成變數,變數取值是由需求來決定的,去除了switch判斷的麻煩。