打造屬于自己的設計模式
2011-09-05 12:05 熬夜的蟲子 閱讀(1091) 評論(4) 收藏 舉報設計模式 一般初級、中級、高級程序員都喜歡掛在嘴邊的詞。想必大家身邊也有不少關于設計模式的書。設計模式是程序員的老前輩們根據自己的項目經驗積累起來的解決方案集。所以,沒必要把設計模式看成是硬性的東西,別人的經驗參考一下即可,了解設計思路,為什么這種場景要用這種模式。也許是老一輩的程序員們確實比現在的程序員要強很多,畢竟現在網上很難找到自己摸索的設計模式了。
蟲子不才就先拋磚引玉了。
簡單介紹2個我項目中經常用到的模式
1.機器人插件模式
何所謂機器人插件,可以這樣理解。你有一個機器人,但是需要這個機器人干什么并不確定。插入不同的卡片可以讓機器人做出不同的行為。原理和aop類似,aop是站在系統級的角度,插件模式基于行為。
直接看代碼
定義行為:
View Code
protected virtual void OnDeleteingRobot(RobotCancelEventArgs e)
{
EventHandler<RobotCancelEventArgs> tmp = DeleteingRobot;
if (tmp != null)
tmp(this, e);
}
public static event EventHandler<RobotCancelEventArgs> bhingRobot;
/// <summary>
/// 機器人行動前觸發事件
/// </summary>
protected virtual void OnbhingRobot(RobotCancelEventArgs e)
{
EventHandler<RobotCancelEventArgs> tmp = bhingRobot;
if (tmp != null)
tmp(this, e);
}
public static event EventHandler<EventArgs> bhedRobot;
/// <summary>
/// 機器人行動后觸發
/// </summary>
protected virtual void OnbhedRobot(EventArgs e)
{
EventHandler<EventArgs> tmp = bhedRobot;
if (tmp != null)
tmp(this, e);
}
public static event EventHandler<ServingEventArgs> ServingRobot;
/// <summary>
/// 調用機器人行為時觸發
/// </summary>
protected virtual void OnServing(ServingEventArgs e)
{
EventHandler<ServingEventArgs> tmp = ServingRobot;
if (tmp != null)
tmp(this, e);
}
行為實例:
View Code
{
Message = string.Empty;
RobotCancelEventArgs e = new RobotCancelEventArgs();
OnServing(e);
if (!e.Cancel)
{
var v = RobotService.bhRobot(this, out Message);
if (v)
{
OnbhedRobot(EventArgs.Empty);
return true;
}
return false;
}
else
{
Message = e.Message;
return false;
}
}
注冊卡片:
View Code
public class CardRobot
{
static CardRobot()
{
Robot.ServingRobot += new EventHandler<ServingEventArgs>(Comment_ServingDelegate);
}
static void Comment_ServingDelegate(object sender, ServingEventArgs e)
{
try
{
//do something
}
catch (Exception ex)
{
//Log4N.WarnLog("BadWordFilterExtension Exception:", ex);
}
}
}
根據自定義屬性反射加載
View Code
{
ExtensionManager.InitExtension();
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
foreach (var item in di.GetFiles("*.dll", System.IO.SearchOption.TopDirectoryOnly))
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(item.FullName);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
object[] attributes = type.GetCustomAttributes(typeof(CommentEngine.Core.ExtensionAttribute), false);
foreach (object attribute in attributes)
{
if (ExtensionManager.ExtensionIsEnable(type.Name))
assembly.CreateInstance(type.FullName);
}
}
}
}
2.單例擴展模式
先看看傳統的單例模式 撇開懶漢式等區分
負責創建Singleton類自己的唯一實例,并提供一個getInstance的方法,讓外部來訪問這個類的唯一實例。
View Code
{
if (instance == null)
{
if (lockKey == null)
lockKey = LockKey;
lock (lockKey)
{
if (instance == null)
{
try
{
if (onCreateInstance == null)
instance = new T();
else
instance = onCreateInstance();
}
catch
{
instance = default(T);
}
}
}
}
return instance;
}
優點:節省系統資源。
適用場景:
當需要控制一個類的實例只能有一個,而且客戶只能從一個全局訪問點訪問它時,可以選用單例模式,這些功能恰好是單例模式要解決的問題。
擴展場景:
海量即時消息,消息處理機制含有復雜邏輯,體積龐大。這個時候你用單例模式可能導致消息不即時,不用單例資源占用太大。
可能有人就會思考,能不能控制實例數目為2個,3個,或者是任意多個呢?目的都是一樣的,節約資源啊,有些時候單個實例不能滿足實際的需要,會忙不過來,根據測算,6個實例剛剛好。
思路很簡單,就是利用上面通過Map來緩存實現單例的示例,進行變形,一個Map可以緩存任意多個實例。
也可以做得更通用一點,將單例的似有構造函數公開。實例的排他性通過對象鎖來實現
部分代碼
View Code
private static int flag = 1;
private static int MAX = 6;
public static Example getInstance()
{
String value = "aoyedechongzi" + flag;
Example Example = map.get(value);
if (Example == null)
{
Example = new Example();
map.put(value, Example);
}
flag++;
if (flag > MAX)
{
flag = 1;
}
return Example;
}
![]() |
原創作品允許轉載,轉載時請務必以超鏈接形式標明文章原始出處以及作者信息。 作者:熬夜的蟲子 點擊查看:博文索引 |


浙公網安備 33010602011771號