前言:
設計模式這本書看過有一段時間了,但是總結的過程一直沒有進行,可能也是因爲淺嘗輒止的學習,實在不知道寫些什麼。但是學習過程是需要的,雖然是一孔之見但是希望在以後的學習中能及時的回過頭來補充和豐富。
從之前的第一次機房收費系統功能實現的喜悅到現在學習了設計模式之後會覺得那種編程是一種不考慮實際應用的代碼實現。作爲面嚮對象語言的三大特性:封裝、繼承、多態。而設計模式的兩大主題:系統複用與系統擴展正好和麪向對象的特性交相呼應,使得設計模式的應用能夠更大程度的優化面向對象編程過程中的不足。下面按照使用的頻率介紹幾種設計模式:
1、 單例模式:
保證一個類僅有一個實例並提供一個訪問它的全局訪問點。 而單例模式中又細分爲餓漢式單例化和懶漢式單例化,區別:類在何時實例化的不同。懶漢式單例化面臨着多線程訪問的安全性問題,所以只有通過雙鎖+判斷的方式才能保證安全。餓漢式單例化是隨着類的加載就實例化出對象,所以即使後面沒有用到的對象也可能已經被實例化,這樣就不可避免的消耗了內存。
(1)懶漢式單例化
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); //在判斷中實例化,需要的才實例化對象
}
return instance;
}
}
(2)餓漢式單例化public class Singleton {
private static Singleton instance = new Singleton(); //在初始化時即實例化,隨着類的加載
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
(3)擴展:static關鍵字
特點:A:可以修飾成員變量和成員方法;B:隨着類的加載而加載 C:優先於對象存在 D:被類的所有對象共享。這其實也是我們判斷該不該使用靜態的依據。舉例:飲水機和水杯的問題思考 F:可以通過類名調用,既可以通過對象名調用,也可以通過類名調用,建議通過類名調用。
靜態的注意事項;A:在靜態方法中沒有this對象。 B:靜態方法只能訪問靜態成員變量和成員方法
2、三個工廠模式
public class OperationFactory{
public static OPeration creatOperate(){
OPeration oper=null;
switch(){
case "+":oper=new OPerationAdd();break
case "-":oper=new OPerationSub();break
case "*":oper=new OPerationMul();break
case "/":oper=new OPerationDiv();break
}
}
}
工廠方法:定義一個用於創建對象的接口,讓子類決定實例化那個類,工廠方法使一個類的實例化延遲到子類。
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(); } }
比較:簡單工廠的優點在於工廠類中包含了必要的邏輯判斷,根據客戶端的條件選擇使用哪一種計算方法,但是如果增加新的方法需要在原有的工廠類中增加,這樣就違反了設計模式的一個很重要的原則開放-封閉原則。工廠方法正是很好的解決了這個缺點,通過對每一種方法建立類,通過接口實現計算工廠達到不需要打開簡單工廠的唯一工廠就可以增加新的功能方法,滿足了擴展性。工廠方法把簡單工廠的內部邏輯判斷轉移到了客戶端,你想要增加功能原本修改工廠類,現在是修改客戶端。
抽象工廠:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
interface IDepartment
{
void Insert(Department department);
IDepartment GetDepartment(int id);
}
class SqlserverDepartment : IDepartment //SqlserverDepartment類,用於訪問sql server的Department
{
public void Insert(Department department)
{
Console.WriteLine("在SQL server中給User表增加一條記錄");
}
public Department GetDaparment(int id)
{
Console.WriteLine("在SQL server中根據ID得到user表中的一條記錄");
return null;
}
}
class AccessDepartment : IDepartment //AccessDepartment類,用於訪問Access的Department
{
public void Insert(Department department)
{
Console.WriteLine("在SQL server中給User表增加一條記錄");
}
public Department GetDaparment(int id)
{
Console.WriteLine("在SQL server中根據ID得到user表中的一條記錄");
return null;
}
}
interface IFactory //IFactory接口,定義一個創建訪問Department對象的抽象的工廠接口
{
IUser CreateUser();
IDepartment CreateDepartment();
}
class SqlserverFactory : IFactory //sqlserverFactory類,實現IFactory接口,實例化sqlserverUser和sqlserverDepartment
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
}
class AccessFactory : IFactory //AccessFactory類,實現IFactory接口,實例化AccessUser和AccessDepartment
{
public IUser CreateUser()
{
return new AccessFactory();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
優點:具體的創建實例過程與客戶端分離,客戶端通過他們的抽象接口操縱實現,產品的具體類名也被具體工廠實現分離。
什麼時候能夠用到抽象工廠:就是能夠像這樣抽象的時候(這個我也不知道該怎麼表達只能意會了)
數據庫訪問的實現:
兩種抽象產品:增加記錄、得到記錄
四種具體產品:SQLserver增加記錄、SQLserver得到記錄、Access增加記錄、Access得到記錄
具體工廠角色:Access、SQLserver
舉例:農場系統的實現
兩種抽象產品:水果、蔬菜
四種具體產品:北方水果,熱帶水果,北方蔬菜,熱帶蔬菜
具體工廠角色:北方工廠,熱帶角色