2025-02-10

對設計模式學瞭有一段的時間瞭,設計模式是軟件工程的基石,他是人們反復使用的,程序員們幾十年的經驗總結,以“開放—封閉”、“單一職責”、“依賴倒轉”、“裡氏代換”、“合成聚合復用”、“迪米特法則”、“接口隔離”為基本原則。

 


         本篇博客我對創建型模式進行總結,其中包括:單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式。

 


1.      單例模式

        這是最簡單的一個模式,保證一個類僅有一個實例,並提供一個訪問他的全局訪問點。可以嚴格的控制客戶怎樣訪問它以及何時訪問它。簡單地說就是對唯一實例的受控訪問。它的秘密武器是創建私有的構造函數。(就像中國隻能有一個,任何人不可分割)

UML圖:

 

 

代碼:

view plaincopy to clipboardprint?namespace 單例模式 

    class Class1 
    { 
        static void Main(string[] args) 
        { 
            Singleto s1 = Singleto.GetInstance(); 
            Singleto s2 = Singleto.GetInstance(); 
            //Singleto s3 = new Singleto();  
            if (s1 == s2) 
            { 
                Console.WriteLine("兩個對象是相同的實例"); 
            } 
            Console.Read(); 
        } 
    } 
    class Singleto 
    { 
        private static Singleto instance; 
 
        private Singleto() //讓構造方法私有,不能使用new實例化  
        { } 
 
        public static Singleto GetInstance() 
        { 
            if (instance == null) 
            { 
                instance = new Singleto(); 
            } 
            return instance; 
        } 
    } 

namespace 單例模式
{
    class Class1
    {
        static void Main(string[] args)
        {
            Singleto s1 = Singleto.GetInstance();
            Singleto s2 = Singleto.GetInstance();
            //Singleto s3 = new Singleto();
            if (s1 == s2)
            {
                Console.WriteLine("兩個對象是相同的實例");
            }
            Console.Read();
        }
    }
    class Singleto
    {
        private static Singleto instance;

        private Singleto() //讓構造方法私有,不能使用new實例化
        { }

        public static Singleto GetInstance()
        {
            if (instance == null)
            {
                instance = new Singleto();
            }
            return instance;
        }
    }
}

 

 

 

2 . 工廠方法模式

       定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。(就像服裝生產工廠,有專門生產襪子的工廠,有專門生產內衣的工廠)

UML圖:

 

 

 

代碼:

view plaincopy to clipboardprint?namespace 工廠模式 

    class Class1 
    { 
        static void Main(string[] args) 
        { 
            IFactory operFactory = new AddFactory(); 
            Operation oper = operFactory.CreateOperation(); 
            oper.NumberA = 1; 
            oper.NumberB = 2; 
            double result = oper.GetResult(); 
            Console.WriteLine(result ); 
        } 
    } 
    interface IFactory   //工廠接口  
    { 
        Operation CreateOperation(); 
    } 
    class AddFactory : IFactory    //加法工廠  
    { 
 
        public Operation CreateOperation() 
        { 
            return new OperationAdd(); 
        } 
    } 
    class SubFactory : IFactory    //減法工廠  
    { 
 
        public Operation CreateOperation() 
        { 
            return new OperationSub(); 
        } 
    } 
    class MulFactory : IFactory    //乘法工廠  
    { 
 
        public Operation CreateOperation() 
        { 
            return new OperationMul(); 
        } 
    } 
    class DivFactory : IFactory    //除法工廠  
    { 
 
        public Operation CreateOperation() 
        { 
            return new OperationDiv(); 
        } 
    } 
 
public class Operation         //抽象運算類  
    { 
        private double _numberA = 0; 
        private double _numberB; 
        public double NumberA 
        { 
            get { return _numberA; } 
            set { _numberA = value; } 
        } 
        public double NumberB 
        { 
            get { return _numberB; } 
            set { _numberB = value; } 
        } 
        public virtual double GetResult() 
        { 
            double result=0; 
            return result; 
        } 
    } 
    class OperationAdd : Operation        //加法類  
    { 
        public override double GetResult() 
        { 
            double result=0; 
            result = NumberA + NumberB; 
            return result; 
        } 
    } 
    class OperationSub : Operation        //減法類  
    { 
        public override double GetResult() 
        { 
            double result=0; 
            result = NumberA – NumberB; 
            return result; 
        } 
    } 
    class OperationMul : Operation        //乘法類  
    { 
        public override double GetResult() 
        { 
            double result=0; 
            result = NumberA * NumberB; 
            return result; 
        } 
    } 
    class OperationDiv : Operation        //除法類  
    { 
        public override double GetResult() 
        { 
            double result=0; 
            if (NumberB == 0) 
                throw new Exception("除數不能為0"); 
            result = NumberA /NumberB; 
            return result; 
        } 
    } 
 
 

namespace 工廠模式
{
    class Class1
    {
        static void Main(string[] args)
        {
            IFactory operFactory = new AddFactory();
            Operation oper = operFactory.CreateOperation();
            oper.NumberA = 1;
            oper.NumberB = 2;
            double result = oper.GetResult();
            Console.WriteLine(result );
        }
    }
    interface IFactory   //工廠接口
    {
        Operation CreateOperation();
    }
    class AddFactory : IFactory    //加法工廠
    {

        public Operation CreateOperation()
        {
            return new OperationAdd();
        }
    }
    class SubFactory : IFactory    //減法工廠
    {

        public Operation CreateOperation()
        {
            return new OperationSub();
        }
    }
    class MulFactory : IFactory    //乘法工廠
    {

        public Operation CreateOperation()
        {
            return new OperationMul();
        }
    }
    class DivFactory : IFactory    //除法工廠
    {

        public Operation CreateOperation()
        {
            return new OperationDiv();
        }
    }

public class Operation         //抽象運算類
    {
        private double _numberA = 0;
        private double _numberB;
        public double NumberA
        {
            get { return _numberA; }
            set { _numberA = value; }
        }
        public double NumberB
        {
            get { return _numberB; }
            set { _numberB = value; }
        }
        public virtual double GetResult()
        {
            double result=0;
            return result;
        }
    }
    class OperationAdd : Operation        //加法類
    {
        public override double GetResult()
        {
            double result=0;
            result = NumberA + NumberB;
            return result;
        }
    }
    class OperationSub : Operation        //減法類
    {
        public override double GetResult()
        {
            double result=0;
            result = NumberA – NumberB;
            return result;
        }
    }
    class OperationMul : Operation        //乘法類
    {
        public override double GetResult()
        {
            double result=0;
            result = NumberA * NumberB;
            return result;
        }
    }
    class OperationDiv : Operation        //除法類
    {
        public override double GetResult()
        {
            double result=0;
            if (NumberB == 0)
                throw new Exception("除數不能為0");
            result = NumberA /NumberB;
            return result;
        }
    }


}


3 . 抽象工廠模式

       提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類,創建不同的產品對象,客戶端應使用不同的具體工廠(就像adidas工廠專門生產這個牌子的鞋、衣服、等裝備,NIKE專門生產這個牌子的鞋、衣服、等裝備)

UML圖:

 

 

 

代碼:

view plaincopy to clipboardprint?namespace 抽象工廠模式 

    class Class2 
    { 
        static void Main(string[] args) 
        { 
            User user = new User(); 
            Department dept = new Department(); 
 
            //IFactory factory = new SqlServerFactory2();  
            IFactory2 factory = new AccessFactory2(); 
            IUser iu = factory.CreateUser(); 
 
            iu.Insert(user); 
            iu.GetUser(1); 
 
            IDepartment id = factory.CreateDepartment(); 
            id.Insert(dept); 
            id.GetDepartment(1); 
 
            Console.Read(); 
        } 
    } 
    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 ;} 
        } 
    } 
    interface IDepartment 
    { 
        void Insert(Department department); 
        Department GetDepartment(int id); 
    } 
    class SqlserverDepartment : IDepartment 
    { 
 
        public void Insert(Department department) 
        { 
            Console.WriteLine("在SQL Server中給Department表增加一條記錄"); 
        } 
 
        public Department GetDepartment(int id) 
        { 
            Console.WriteLine("在SQL Server中根據ID得到Department表的一條記錄"); 
            return null; 
        } 
    } 
    class AccessDepartment : IDepartment 
    { 
        public void Insert(Department department) 
        { 
            Console.WriteLine("在Access中給Department表添加一條記錄"); 
        } 
        public Department GetDepartment(int id) 
        { 
            Console.WriteLine("在Access中根據ID得到Department表的一條記錄"); 
            return null; 
        } 
    } 
    interface IFactory2 
    { 
        IUser CreateUser(); 
        IDepartment CreateDepartment(); 
    } 
    class SqlServerFactory2 : IFactory2 
    { 
 
        public IUser CreateUser() 
        { 
            return new SqlserverUser1(); 
        } 
 
        public IDepartment CreateDepartment() 
        { 
            return new SqlserverDepartment() ; 
        } 
    } 
    class AccessFactory2 : IFactory2 
    { 
 
        public IUser CreateUser() 
        { 
            return new AccessUser1(); 
        } 
 
        public IDepartment CreateDepartment() 
        { 
            return new AccessDepartment(); 
        } 

interface IUser      //用戶接口  
    { 
        void Insert(User user); 
        User GetUser(int id); 
    } 
    class SqlserverUser1 : IUser 
    { 
 
        public void Insert(User user) 
        { 
            Console.WriteLine("在sql server中給User表增加一條記錄"); 
        } 
 
        public User GetUser(int id) 
        { 
            Console.WriteLine("在SQL Server中根據ID得到User表一條記錄"); 
            return null; 
        } 
    } 
    class AccessUser1 : IUser 
    { 
 
        public void Insert(User user) 
        { 
            Console.WriteLine("在Access表User中增加一條記錄");             
        } 
 
        public User GetUser(int id) 
        { 
            Console.WriteLine("在Access中根據ID得到User表一條記錄"); 
            return null; 
        } 
    } 
 

namespace 抽象工廠模式
{
    class Class2
    {
        static void Main(string[] args)
        {
            User user = new User();
            Department dept = new Department();

            //IFactory factory = new SqlServerFactory2();
            IFactory2 factory = new AccessFactory2();
            IUser iu = factory.CreateUser();

            iu.Insert(user);
            iu.GetUser(1);

            IDepartment id = factory.CreateDepartment();
            id.Insert(dept);
            id.GetDepartment(1);

            Console.Read();
        }
    }
    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 ;}
        }
    }
    interface IDepartment
    {
        void Insert(Department department);
        Department GetDepartment(int id);
    }
    class SqlserverDepartment : IDepartment
    {

        public void Insert(Department department)
        {
            Console.WriteLine("在SQL Server中給Department表增加一條記錄");
        }

        public Department GetDepartment(int id)
        {
            Console.WriteLine("在SQL Server中根據ID得到Department表的一條記錄");
            return null;
        }
    }
    class AccessDepartment : IDepartment
    {
        public void Insert(Department department)
        {
            Console.WriteLine("在Access中給Department表添加一條記錄");
        }
        public Department GetDepartment(int id)
        {
            Console.WriteLine("在Access中根據ID得到Department表的一條記錄");
            return null;
        }
    }
    interface IFactory2
    {
        IUser CreateUser();
        IDepartment CreateDepartment();
    }
    class SqlServerFactory2 : IFactory2
    {

        public IUser CreateUser()
        {
            return new SqlserverUser1();
        }

        public IDepartment CreateDepartment()
        {
            return new SqlserverDepartment() ;
        }
    }
    class AccessFactory2 : IFactory2
    {

        public IUser CreateUser()
        {
            return new AccessUser1();
        }

        public IDepartment CreateDepartment()
        {
            return new AccessDepartment();
        }
}
interface IUser      //用戶接口
    {
        void Insert(User user);
        User GetUser(int id);
    }
    class SqlserverUser1 : IUser
    {

        public void Insert(User user)
        {
            Console.WriteLine("在sql server中給User表增加一條記錄");
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在SQL Server中根據ID得到User表一條記錄");
            return null;
        }
    }
    class AccessUser1 : IUser
    {

        public void Insert(User user)
        {
            Console.WriteLine("在Access表User中增加一條記錄");           
        }

        public User GetUser(int id)
        {
            Console.WriteLine("在Access中根據ID得到User表一條記錄");
            return null;
        }
    }

}
 

 

 

4. 建造者模式

        將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。(就像蓋一個大樓,房地產商要先找挖地基的工人幹活,再找蓋樓的人幹活,再找做外圍包裝的工人幹活)

UML圖:

 


代碼:

view plaincopy to clipboardprint?namespace 建造者模式 

    class Class2 
    { 
        static void Main(string[] args) 
        { 
            Director2 director = new Director2(); 
            Builder2 b1 = new ConcreateBuilder1(); 
            Builder2 b2 = new ConcreateBuilder2(); 
             
            director.Construct(b1); 
            Product p1 = b1.GetResult(); 
            p1.Show(); 
 
            director.Construct(b2); 
            Product p2 = b2.GetResult(); 
            p2.Show(); 
 
            Console.Read(); 
        } 
         
    } 
    class Product              //產品類,由多個部件構成  
    { 
        IList<string> parts = new List<string>(); 
 
        public void Add(string part) 
        { 
            parts.Add(part); 
        } 
        public void Show() 
        { 
            Console.WriteLine("\n產¨²品¡¤ 創ä¡ä建¡§—a—a"); 
            foreach (string part in parts)     //列出所有產品的部件  
            { 
                Console.WriteLine(part ); 
            } 
        } 
    } 
    abstract class Builder2   //抽象建造者,確定建造者的組成部分  
    { 
        public abstract void BuildPartA(); 
        public abstract void BuildPartB(); 
        public abstract Product GetResult(); 
    } 
    class ConcreateBuilder1 : Builder2    //具體建造者ConcreateBuilder1——工人  
    { 
        private Product product = new Product(); 
        public override void BuildPartA() 
        { 
            product.Add("部件A"); 
        } 
 
        public override void BuildPartB() 
        { 
            product.Add("部件B"); 
        } 
 
        public override Product GetResult() 
        { 
            return product; 
        } 
    } 
    class ConcreateBuilder2 : Builder2    //具體建造者ConcreateBuilder2——工人  
    { 
        private Product product = new Product(); 
        public override void BuildPartA() 
        { 
            product.Add("部件X"); 
        } 
 
        public override void BuildPartB() 
        { 
            product.Add("部件Y"); 
        } 
 
        public override Product GetResult() 
        { 
            return product; 
        } 
    } 
 
    class Director2  //指揮者類——設計師  
    { 
        public void Construct(Builder2 builder) 
        {         //用來指揮建造者的過程  
            builder.BuildPartA(); 
            builder.BuildPartB(); 
        } 
    } 

namespace 建造者模式
{
    class Class2
    {
        static void Main(string[] args)
        {
            Director2 director = new Director2();
            Builder2 b1 = new ConcreateBuilder1();
            Builder2 b2 = new ConcreateBuilder2();
           
            director.Construct(b1);
            Product p1 = b1.GetResult();
            p1.Show();

            director.Construct(b2);
            Product p2 = b2.GetResult();
            p2.Show();

            Console.Read();
        }
       
    }
    class Product              //產品類,由多個部件構成
    {
        IList<string> parts = new List<string>();

        public void Add(string part)
        {
            parts.Add(part);
        }
        public void Show()
        {
            Console.WriteLine("\n產¨²品¡¤ 創ä¡ä建¡§—a—a");
            foreach (string part in parts)     //列出所有產品的部件
            {
                Console.WriteLine(part );
            }
        }
    }
    abstract class Builder2   //抽象建造者,確定建造者的組成部分
    {
        public abstract void BuildPartA();
        public abstract void BuildPartB();
        public abstract Product GetResult();
    }
    class ConcreateBuilder1 : Builder2    //具體建造者ConcreateBuilder1——工人
    {
        private Product product = new Product();
        public override void BuildPartA()
        {
            product.Add("部件A");
        }

        public override void BuildPartB()
        {
            product.Add("部件B");
        }

        public override Product GetResult()
        {
            return product;
        }
    }
    class ConcreateBuilder2 : Builder2    //具體建造者ConcreateBuilder2——工人
    {
        private Product product = new Product();
        public override void BuildPartA()
        {
            product.Add("部件X");
        }

        public override void BuildPartB()
        {
            product.Add("部件Y");
        }

        public override Product GetResult()
        {
            return product;
        }
    }

    class Director2  //指揮者類——設計師
    {
        public void Construct(Builder2 builder)
        {         //用來指揮建造者的過程
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }
}

 

5. 原型模式

        用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。其實就是從一個對象再創建另一個可定制的對象,而且不需要知道任何創建的細節。秘密武器:克隆自身(不知道大傢見過做月餅的模子沒有,就像它,用這個模子可以做出一個一樣的東西,做出來之後還可以稍微修改一下成為你想要的形狀)

UML圖:

 


代碼:

view plaincopy to clipboardprint?//9.5簡歷的淺復制  
namespace 原型模式 

    class Class3 
    { 
        static void Main(string[] args) 
        { 
            Resume2 a = new Resume2("大鳥"); 
            a.SetPersonalInfo("男","29"); 
            a.SetWorkExpersonalInfo("1998-2000","XX公司"); 
 
            Resume2 b = (Resume2)a.Clone(); 
            b.SetWorkExpersonalInfo("2000-2006","YY公司"); 
 
            Resume2 c = (Resume2)a.Clone(); 
            c.SetPersonalInfo("男","33"); 
            c.SetWorkExpersonalInfo("1900-1937","ZZ公司"); 
 
            a.Display(); 
            b.Display(); 
            c.Display(); 
 
            Console.Read(); 
        } 
    } 
    class WorkExperience       //工作經歷  
    { 
        private string workDate; 
        public string WorkDate 
        { 
            get { return workDate; } 
            set { workDate = value; } 
        } 
        private string company; 
        public string Company 
        { 
            get { return company; } 
            set { company = value; } 
        } 
    } 
    class Resume2 : ICloneable      //簡歷  
    { 
        private string name; 
        private string sex; 
        private string age; 
        private WorkExperience work; 
 
        public Resume2(string name) 
        { 
            this.name = name; 
            work = new WorkExperience(); 
        } 
        public void SetPersonalInfo(string sex, string age) 
        { 
            this.sex = sex; 
            this.age = age; 
        } 
        public void SetWorkExpersonalInfo(string workDate, string company) 
        { 
            work.WorkDate = workDate; 
            work.Company = company; 
        } 
        public void Display() 
        { 
            Console.WriteLine("{0}{1}{2}",name,sex,age ); 
            Console.WriteLine("工作經歷:{0}{1}",work.WorkDate,work.Company ); 
        } 
 
        /* MemberwiseClone 方法創建一個淺表副本,具體來說就是創建一個新的對象
         * 然後將當前對象的非靜態字段復制到該新對象,如果字段是子類型
         * 則對該字段進行逐位的復制,如果是引用則復制引用但不復制
         * 引用的對象;因此,原始對象及其副本引用同一對象
         */  
        public Object Clone() 
        { 
            return (Object)this.MemberwiseClone();    //淺復制,引用都指向同一個對象  
        } 
    } 

作者“許德鵬的專欄”
 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *