對設計模式學瞭有一段的時間瞭,設計模式是軟件工程的基石,他是人們反復使用的,程序員們幾十年的經驗總結,以“開放—封閉”、“單一職責”、“依賴倒轉”、“裡氏代換”、“合成聚合復用”、“迪米特法則”、“接口隔離”為基本原則。
本篇博客我對創建型模式進行總結,其中包括:單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式。
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(); //淺復制,引用都指向同一個對象
}
}
}
作者“許德鵬的專欄”