系统架构师-基础到企业应用架构-企业应用架构
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
一、上篇回顧
????? 我們先來(lái)回顧下上篇講解的內(nèi)容,我們前面的幾節(jié)分別講述了,業(yè)務(wù)邏輯層、數(shù)據(jù)訪問(wèn)層、服務(wù)層、表現(xiàn)層,我們了解了這些分層的職責(zé)和分層之間的大概的關(guān)聯(lián)
關(guān)系,本篇可能主要是簡(jiǎn)單的介紹下企業(yè)應(yīng)用的幾類(lèi)模式,結(jié)合這幾個(gè)分層直接的交互來(lái)完成系統(tǒng)功能的構(gòu)建。我們還是先對(duì)我們學(xué)習(xí)的四個(gè)分層的職責(zé)和功能做個(gè)大
概的回顧,我們先來(lái)看看下圖來(lái)回顧下我們講述的內(nèi)容。
?????
????? 我想通過(guò)上圖,大家能回憶起我們講述的相關(guān)內(nèi)容,然后整理好自己的思路,我們本文將會(huì)針對(duì)這幾個(gè)分層進(jìn)行相應(yīng)的模式的講解,并且會(huì)結(jié)合實(shí)例來(lái)說(shuō)明企業(yè)應(yīng)
用架構(gòu)的簡(jiǎn)單應(yīng)用。我想這也是大家關(guān)心的內(nèi)容,我也希望大家能多提出寶貴意見(jiàn),大家共同提高。
????? 之前說(shuō)是提供PDF文件的下載的,以提供給需要學(xué)習(xí)的朋友更方便的形式,但是由于最近時(shí)間有限,沒(méi)能整理好,等過(guò)陣子提供一個(gè)完整的整合好的PDF版本,提
供給大家下載,還望大家見(jiàn)諒。
二、開(kāi)篇
????? 本篇我們將針對(duì)我們前面講述的幾個(gè)分層做個(gè)簡(jiǎn)單的整合,就是通過(guò)一個(gè)簡(jiǎn)單的實(shí)例代碼來(lái)說(shuō)明下,我們給出的一個(gè)可能的企業(yè)應(yīng)用架構(gòu)模式去完成企業(yè)應(yīng)用,并
且順帶分析下,企業(yè)應(yīng)用中可能存在的瓶頸等,當(dāng)然可能本章只是點(diǎn)出一些概念,然后在后面的章節(jié)中去完成,比如我們的性能優(yōu)化,性能瓶頸等,這些我們后面通過(guò)
這篇:系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-性能優(yōu)化(架構(gòu)瓶頸)(后續(xù)篇)詳細(xì)的分析。當(dāng)然由于本章主要是基于前面講述的內(nèi)容的一個(gè)整合和分析,可能部分觀點(diǎn)
還有更好的改進(jìn)方案,還希望大家多提出寶貴意見(jiàn)和您的建議,謝謝!那么我們先來(lái)看看我們本章講述的內(nèi)容吧:
?????
????? 本章主要講述下各分層之間的交互方式及可行的設(shè)計(jì)方案,并且分析我們?cè)诿總€(gè)分層采用什么樣的模式,及給出相應(yīng)的示例代碼,當(dāng)然這里可能講述的不會(huì)是最好
的實(shí)現(xiàn)方案,還期待大家提出更好的改進(jìn)方案。
三、本文提綱
????? 1、內(nèi)容回顧
????? 2、開(kāi)篇
????? 3、本文提綱
????? 4、企業(yè)應(yīng)用架構(gòu)實(shí)例
??????????? 4.1、企業(yè)應(yīng)用架構(gòu)中的物理分層
??????????? 4.2、數(shù)據(jù)訪問(wèn)層分析
??????????? 4.3、業(yè)務(wù)邏輯層分析
??????????? 4.4、服務(wù)層分析
??????????? 4.5、表現(xiàn)層分析
??????????? 4.6、分析總結(jié)
????? 5、結(jié)束語(yǔ)
????? 6、系列進(jìn)度
????? 7、下篇預(yù)告
四、企業(yè)應(yīng)用架構(gòu)實(shí)例
???????? 4.1、企業(yè)應(yīng)用架構(gòu)的物理分層
????? 本節(jié)將會(huì)分層的相關(guān)介紹,并且分析分層的原因,為下篇:系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-分層[上篇] 做鋪墊。
???? 分層我想對(duì)大家來(lái)說(shuō)都不會(huì)太陌生。因?yàn)槲覀兤綍r(shí)在開(kāi)發(fā)的過(guò)程中一般都是采用分層架構(gòu)的方式,通過(guò)分層將系統(tǒng)的功能進(jìn)行劃分,我們將系
統(tǒng)中的若干有共同特征的部分放在一個(gè)分層中,然后通過(guò)分層之間的交互去完成系統(tǒng)的功能。
???? 我們看看企業(yè)應(yīng)用的幾種應(yīng)用程序模式:
?????
??? 1、單擊應(yīng)用程序就是一些本地服務(wù)的應(yīng)用程序,這個(gè)應(yīng)該沒(méi)啥特別的難度,例如Office應(yīng)用程序,當(dāng)然現(xiàn)在有在線版本的Office,這個(gè)應(yīng)用的太多了。
??? 2、客戶(hù)端/服務(wù)器的形式,特別是在WinForm、WPF、SilverLight方面的應(yīng)用等,例如我們的常用的OutLook,雖然不是采用.NET平臺(tái)開(kāi)發(fā)的,但是原理一樣就
是通過(guò)客戶(hù)端通過(guò)通信服務(wù)來(lái)訪問(wèn)服務(wù)器,然后取回相應(yīng)的郵件信息返回給客戶(hù)端,相當(dāng)于我們通過(guò)客戶(hù)端的形式來(lái)訪問(wèn)Web服務(wù)。
??? 3、Web服務(wù):通過(guò)將開(kāi)發(fā)的Web服務(wù)器部署在服務(wù)器上,然后我們就可以通過(guò)輸入HTTP網(wǎng)址的形式來(lái)訪問(wèn)web服務(wù),我們這里是通過(guò)瀏覽器來(lái)完成的,其實(shí)這個(gè)
模式也是客戶(hù)端/服務(wù)器的形式。只不過(guò)這時(shí)的客戶(hù)端變成瀏覽器+服務(wù)頁(yè)面,然后通過(guò)瀏覽器來(lái)完成Web服務(wù)的訪問(wèn)。
??? 4、其他服務(wù):我們這里主要是針對(duì)一些其他的設(shè)備,例如通信設(shè)備等方面的訪問(wèn),比如說(shuō)我們現(xiàn)在提供一個(gè)衛(wèi)星定位的服務(wù),那么通過(guò)設(shè)備調(diào)用服務(wù)來(lái)完成,告知
用戶(hù)的GPS定位信息等。很多這個(gè)方面的應(yīng)用。這個(gè)方向應(yīng)該是未來(lái)的一個(gè)主流吧。
??? 我們上面簡(jiǎn)單的講述了系統(tǒng)的物理分層的形式,那么我們來(lái)看看如何對(duì)系統(tǒng)的功能進(jìn)行分層,也就是我們下面要詳細(xì)講解的實(shí)例分析。
? ???? 4.2、數(shù)據(jù)訪問(wèn)層分析
???? 數(shù)據(jù)訪問(wèn)層我們知道是唯一一個(gè)可以與數(shù)據(jù)庫(kù)之間直接進(jìn)行交互的分層,數(shù)據(jù)訪問(wèn)層必須滿(mǎn)足的幾個(gè)功能和職責(zé),我們這里就不復(fù)述了,我們本篇可能就是直接給
出數(shù)據(jù)訪問(wèn)層的相關(guān)實(shí)現(xiàn),并且分析出數(shù)據(jù)訪問(wèn)層與其他層之間的交互。
????? 大家可能一看就知道是什么意思,可能在您的眼中應(yīng)該就和你們平時(shí)項(xiàng)目中采用的分層結(jié)構(gòu)有點(diǎn)類(lèi)似吧。
????? 我這里的數(shù)據(jù)訪問(wèn)層提供所有的數(shù)據(jù)庫(kù)訪問(wèn)服務(wù)。我們來(lái)看看基本的服務(wù)功能吧
????? 我們這里定義了一個(gè)DDL語(yǔ)句操作的枚舉,CUD的枚舉,因?yàn)槲覀兲峁┝艘粋€(gè)統(tǒng)一的數(shù)據(jù)訪問(wèn)服務(wù),通過(guò)Excute來(lái)完成。
/// <summary> /// 數(shù)據(jù)訪問(wèn)操作類(lèi)型 /// </summary> public enum DDLType { Create, Update, Delete }???? 這里用枚舉來(lái)定義數(shù)據(jù)庫(kù)字段與查詢(xún)條件值之間的關(guān)系
/// <summary> /// 數(shù)據(jù)字段與字段值之間的關(guān)系表達(dá)式 /// </summary> public enum FieldExpressionType { EquleTo, BeginThen, LessThen, BetweenAnd, Like }??? 我們?cè)賮?lái)看看我們定義的查詢(xún)條件的接口
/// <summary> /// 定義子查詢(xún)接口 /// </summary> public interface ICondition { int Add(string fieldName,object value,FieldExpressionType fetType); int Add(ICondition condition); string WhereCondition; string OrderCondition; }??? 數(shù)據(jù)訪問(wèn)層接口代碼
/// <summary> /// 定義統(tǒng)一的數(shù)據(jù)訪問(wèn)服務(wù) /// </summary> public interface IDataAccess { #region CUD int Create<T>(T item); int Update<T>(T item); int Delete<T>(T item); int Execute<T>(T item,DDLType ddlType); #endregion #region Read服務(wù) List<T> Query<T>(ICondition condition); T GetModelByPrimaryKey<T>(object key); List<T> GetAll<T>(); #endregion #region 事務(wù)操作 void BeginTransaction(); bool Commit(); bool RollBack(); bool IsTransaction; #endregion }??? 我們知道具體的代碼我們是通過(guò)反射+特性的形式來(lái)完成數(shù)據(jù)庫(kù)操作語(yǔ)句的生成的,我們來(lái)看看可行的代碼,屬性項(xiàng)特性的定義。
/// <summary> /// Model中的字段屬性特性 /// </summary> [AttributeUsage(AttributeTargets.All, AllowMultiple = false)] public class PropertyAttribute : Attribute { private string dbColumnName; private bool isPrimary; private DbType dbType; private object defaultValue; private bool isIdentify; private int length; public string DbColumnName { get { return this.dbColumnName; } set { this.dbColumnName = value; } } public bool IsPrimary { get { return this.isPrimary; } set { this.isPrimary = value; } } public bool IsIdentify { get { return this.isIdentify; } set { this.isIdentify = value; } } public DbType DbType { get { return this.dbType; } set { this.dbType = value; } } public object DefaultValue { get { return this.defaultValue; } set { this.defaultValue = value; } } public int DbLength { get { return this.length; } set { this.length = value; } } public PropertyAttribute(string dbName, bool isPrimery, DbType type,object dValue) { this.dbColumnName = dbName; this.isPrimary = isPrimery; this.dbType = type; this.defaultValue = this.GetDefaultValue(); } private object GetDefaultValue() { return new object(); } public PropertyAttribute(string dbName) { this.dbColumnName = dbName; this.isPrimary = false; this.dbType = DbType.String; this.defaultValue = this.GetDefaultValue(); } public PropertyAttribute(string dbName,bool isPrimery) { this.dbColumnName = dbName; this.isPrimary = isPrimery; this.dbType = DbType.String; this.defaultValue = this.GetDefaultValue(); } public PropertyAttribute(string dbName, bool isPrimery, DbType type) { this.dbColumnName = dbName; this.isPrimary = isPrimery; this.dbType = type; this.defaultValue = null; } }??? 我們?cè)賮?lái)看看基于表上的特性
/// <summary> /// 基于表的自定義特性類(lèi) /// </summary> [AttributeUsage(AttributeTargets.All, AllowMultiple = false)] public class TableAttribute : Attribute { private string dbTableName; public TableAttribute(string dbName) { this.dbTableName = dbName; } public string TableName { get { return this.dbTableName; } set { this.dbTableName = value; } } }根據(jù)反射取出表名/// <summary> /// 返回Model對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model"></param> /// <returns></returns> public string DbTableName<T>(T model) { string dbName = string.Empty; DPM.Common.TableAttribute attr = null; object[] attributes = model.GetType().GetCustomAttributes(typeof(DPM.Common.TableAttribute), true); if (attributes.Length > 0) { attr = (DPM.Common.TableAttribute)attributes[0]; } if (attr != null) dbName = attr.TableName; return dbName; }根據(jù)反射取出表中的列/// <summary> /// 動(dòng)態(tài)創(chuàng)建表中字段列表 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model"></param> /// <returns></returns> public string InitDbColumns<T>(T model) { StringBuilder commandBuilder = new StringBuilder(); DPM.Common.PropertyAttribute attr = null; foreach (PropertyInfo property in model.GetType().GetProperties()) { object[] attributes = property.GetCustomAttributes(typeof(DPM.Common.PropertyAttribute), true); if (attributes.Length > 0) { attr = (DPM.Common.PropertyAttribute)attributes[0]; } if(commandBuilder.length>0)commandBuilder.Append(“,”);commandBuilder.Append(attr.DbColumnName); } return commandBuilder.ToString(); }?????? 當(dāng)然這里只是給出了簡(jiǎn)單的示例,我們來(lái)看看生成的Insert 語(yǔ)句的格式吧
/// <summary> /// 動(dòng)態(tài)創(chuàng)建表中字段更新列表 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="model"></param> /// <returns></returns> public string InitInsertColumns<T>(T model) { StringBuilder filedBuilder = new StringBuilder(); StringBuilder valueBuilder = new StringBuilder(); StringBuilder commandBuilder = new StringBuilder(); DPM.Common.PropertyAttribute attr = null; foreach (PropertyInfo property in model.GetType().GetProperties()) { object[] attributes = property.GetCustomAttributes(typeof(DPM.Common.PropertyAttribute), true); if (attributes.Length > 0) { attr = (DPM.Common.PropertyAttribute)attributes[0]; } if (attr.DbColumnName == "") continue; if (attr.IsIdentify) continue; if (filedBuilder.Length > 0) { filedBuilder.Append("," + attr.DbColumnName); valueBuilder.Append("," + property.GetValue(model, null)); } else { filedBuilder.Append(attr.DbColumnName); valueBuilder.Append(property.GetValue(model, null)); } } commandBuilder.Append(SqlDMLText.LKH); commandBuilder.Append(filedBuilder.ToString()); commandBuilder.Append(SqlDMLText.RKH); commandBuilder.Append(SqlDMLText.VALUES); commandBuilder.Append(SqlDMLText.LKH); commandBuilder.Append(valueBuilder.ToString()); commandBuilder.Append(SqlDMLText.RKH); return commandBuilder.ToString(); }?????? 其他的語(yǔ)句類(lèi)似了,這部分詳細(xì)的代碼我們會(huì)在ORM篇詳細(xì)的講述,并且對(duì)反射的性能通過(guò)優(yōu)化來(lái)提供性能。
?????? 我們來(lái)總結(jié)下數(shù)據(jù)訪問(wèn)層應(yīng)該有的功能吧。我認(rèn)為應(yīng)該提供以下的功能
?????? 這樣的一個(gè)數(shù)據(jù)訪問(wèn)層基本上能夠滿(mǎn)足功能的需要。當(dāng)然我這里就不把代碼全部貼出來(lái)了,太多
了,我們接下來(lái)講講業(yè)務(wù)邏輯層吧。
????????? 4.3、業(yè)務(wù)邏輯層分析
????? 上篇我們貼出來(lái)了一些比較典型的數(shù)據(jù)訪問(wèn)層的代碼,當(dāng)然沒(méi)有上全部的代碼,本文將會(huì)提供demo實(shí)例下載,大家可以參考其中的部分代碼。我們來(lái)看看業(yè)務(wù)層
中的每個(gè)業(yè)務(wù)對(duì)象應(yīng)該具有什么樣的智能呢?我們知道我們這里不建議業(yè)務(wù)對(duì)象直接來(lái)訪問(wèn)數(shù)據(jù)訪問(wèn)層,那么我們?nèi)绾螌?shí)現(xiàn)持久化透明的方式呢?我記得之前我講述業(yè)
務(wù)邏輯層的時(shí)候也提到這個(gè)方面的要求了,還有不少熱心的園友問(wèn)我如何實(shí)現(xiàn),我這里給出幾個(gè)可能的辦法,當(dāng)然如果有更好的辦法,還請(qǐng)大家多多提出。我這里給出
個(gè)簡(jiǎn)單的業(yè)務(wù)對(duì)象的職責(zé),當(dāng)然我這里給出的職責(zé)是我理解的在我的這個(gè)實(shí)例中業(yè)務(wù)對(duì)象應(yīng)該具有的職責(zé)。
????? 接下來(lái)我們看看業(yè)務(wù)邏輯層的職責(zé)吧,然后我們給出示例代碼
?????
????? 我們來(lái)舉例說(shuō)明一個(gè)業(yè)務(wù)對(duì)象可能具有的功能吧?我們這里以還是以B2C系統(tǒng)為例吧,我們來(lái)說(shuō)說(shuō)訂單的可能行為吧:
/// <summary> /// 訂單 /// </summary> public class Order { /// <summary> /// 產(chǎn)品列表 /// </summary> private List<Product> products = new List<Product>(); /// <summary> /// 獲取訂單的金額 /// </summary> /// <param name="order"></param> /// <returns></returns> public decimal GetOrderCount(Model.Order order) { decimal totalCount = 0; foreach (Product product in products) { totalCount += product.Cash; } return totalCount; } /// <summary> /// 獲取該訂單下的所有產(chǎn)品 /// </summary> /// <param name="order"></param> /// <returns></returns> public List<Product> GetProduct(Model.Order order) { return new List<Product>(); } }???? 當(dāng)然這里面的取得與訂單相關(guān)的產(chǎn)品列表,因?yàn)槲覀儧](méi)有設(shè)計(jì)在DTO中默認(rèn)包含這個(gè)屬性,那么我們這里其實(shí)可以考慮增加延遲加載的形式,一旦加載后,也可以
第一次加載后,緩存起來(lái),下次使用的過(guò)程中直接取出來(lái)。
????? 我們來(lái)看看與這個(gè)訂單業(yè)務(wù)邏輯相關(guān)的服務(wù)層代碼
/// <summary> /// 訂單服務(wù) /// </summary> public class OrderService { private List<Model.Product> products = new List<Model.Product>(); /// <summary> /// 持久化透明的方式 /// </summary> /// <param name="order"></param> /// <param name="type"></param> /// <returns></returns> public int Execute(Model.Order order,DAL.DDLType type) { return DAL.SQLServer.Instance.Execute(order, type); } /// <summary> /// 獲取訂單的總金額 /// </summary> /// <param name="order"></param> /// <returns></returns> public decimal GetOrderCash(Model.Order order) { BLL.Order = new BLL.Order(order); return order.GetOrderCount(); } /// <summary> /// 保存訂單信息 /// </summary> /// <param name="order"></param> /// <param name="type"></param> /// <returns></returns> public int SaveOrder(Model.Order order, DAL.DDLType type) { int iAff = 0; //將與訂單相關(guān)的產(chǎn)品信息也同步進(jìn)行保存。 //我們這里通過(guò)事務(wù)的方式進(jìn)行處理 try { DAL.SQLServer.Instance.BeginTransaction(); //具體的邏輯 //插入產(chǎn)品信息 foreach (Model.Product product in products) { DAL.SQLServer.Instance.Create(product); iAff++; } //插入訂單信息 iAff+= DAL.SQLServer.Instance.Create(order); DAL.SQLServer.Instance.Commit(); return iAff; } catch { DAL.SQLServer.Instance.RollBack(); return 0; } finally { DAL.SQLServer.Instance.Dispose(); } } }????? 通過(guò)上面的代碼我們可以看出,目前的業(yè)務(wù)邏輯層中的業(yè)務(wù)對(duì)象只是處理自身的相關(guān)業(yè)務(wù)邏輯,通過(guò)服務(wù)層與數(shù)據(jù)層進(jìn)行交互,然后業(yè)務(wù)對(duì)象并不關(guān)系自身的
CRUD的業(yè)務(wù),而是通過(guò)服務(wù)層來(lái)完成的,那么對(duì)于CUD我想大家應(yīng)該沒(méi)有什么爭(zhēng)議,因?yàn)槌志没该髦皇钦f(shuō)把業(yè)務(wù)邏輯層原本通過(guò)繼承或者是實(shí)現(xiàn)接口,或者依賴(lài)注
入的形式來(lái)完成持久化的操作。
????? 我們這里則是將這樣的持久化操作提出來(lái)放在服務(wù)層來(lái)完成,這樣可以降低業(yè)務(wù)層與數(shù)據(jù)訪問(wèn)層的依賴(lài),那么大家肯定關(guān)心如何實(shí)現(xiàn)業(yè)務(wù)邏輯對(duì)象的查詢(xún)服務(wù)呢?
我的思路是這樣的,大家請(qǐng)看看是否合理,或者您有好的思路或者想法一定要告知我,不甚感激!
?????
????? 不知道我們上面的上圖是否表述的很清楚,還請(qǐng)大家多多的批評(píng)指出。當(dāng)然上述的模式,可能在實(shí)際的企業(yè)應(yīng)用中還是有點(diǎn)困難的,還有一種業(yè)務(wù)邏輯層的持久化
透明實(shí)現(xiàn)。就是通過(guò)AOP來(lái)完成,或者是通過(guò)代理類(lèi)來(lái)實(shí)現(xiàn)。這里說(shuō)心里話(huà),我對(duì)AOP的具體實(shí)現(xiàn)并沒(méi)有研究過(guò),但是通過(guò)動(dòng)態(tài)注入的方式的確可以實(shí)現(xiàn)這個(gè)功能。具
體的實(shí)現(xiàn)方式就交給大家來(lái)完成了。
?????? 4.4服務(wù)層分析
????? 服務(wù)層作為協(xié)調(diào)業(yè)務(wù)對(duì)象進(jìn)行相應(yīng)的業(yè)務(wù)流的控制,當(dāng)然服務(wù)層只是協(xié)調(diào)業(yè)務(wù)對(duì)象之間的交互,并不是負(fù)責(zé)具體的業(yè)務(wù)邏輯,這里的服務(wù)層應(yīng)該是只負(fù)責(zé)業(yè)務(wù)對(duì)象
之間的交互。當(dāng)然我這里還把部分對(duì)數(shù)據(jù)完整性,數(shù)據(jù)類(lèi)型等方面的內(nèi)容放在服務(wù)層來(lái)做。下面來(lái)說(shuō)明服務(wù)層可能包含的功能:
?????
????? 我們?cè)跇I(yè)務(wù)邏輯層中也貼出了部分代碼。當(dāng)然服務(wù)層中其實(shí)還可以有很多的內(nèi)容,比如通過(guò)我們?cè)谇懊娴姆?wù)層講解時(shí)介紹的幾個(gè)模式,我們也都是可以在服務(wù)層
中應(yīng)用的。當(dāng)然我們這里的實(shí)例代碼可能就不會(huì)貼出這幾個(gè)模式了,我們這里舉例來(lái)說(shuō)明服務(wù)層中的部分服務(wù)代碼。例如我們前面經(jīng)常舉例說(shuō)明的訂單管理中的提醒功
能。
????? 比如我們有時(shí)候我們的提醒功能,需要郵件提醒或者是短信提醒的幾種服務(wù)方式,這時(shí)候我們可以通過(guò)提供統(tǒng)一的服務(wù)接口,然后不需要單獨(dú)的在界面層去單獨(dú)的
定義,我們通過(guò)接口的形式為后期的變化方便擴(kuò)展,我們來(lái)給出部分代碼:
/// <summary> /// 提醒服務(wù) /// </summary> public interface IAlarmService { /// <summary> /// 發(fā)送消息的服務(wù) /// </summary> /// <param name="reciveObject">接收方</param> /// <param name="title">標(biāo)題</param> /// <param name="content">消息內(nèi)容</param> /// <returns></returns> bool SendMessage(string reciveObject,string title,string content); }我們來(lái)看看郵件提醒服務(wù)的簡(jiǎn)單實(shí)現(xiàn)代碼public class EmailAlarm : IAlarmService { #region IAlarmService 成員 /// <param name="strSmtpServer">郵件服務(wù)器(如果是163郵箱就寫(xiě)smtp.163.com)</param> /// strSmtpServer /// <param name="strFrom">發(fā)件人的帳號(hào)</param> /// strFrom /// <param name="strFromPass">發(fā)件人密碼</param> /// strFromPass public bool SendMessage(string reciveObject, string title, string content) { bool isSuccess = true; MailSetting model = DAL.SQLServer.Instance.GetModelByPrimaryKey<MailSetting>(); try { System.Net.Mail.SmtpClient client = new SmtpClient(model.strSmtpServer); client.UseDefaultCredentials = false; client.Credentials = new System.Net.NetworkCredential(model.strFrom, model.strFromPass); client.DeliveryMethod = SmtpDeliveryMethod.Network; System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(model.strFrom, reciveObject, title, content); message.BodyEncoding = System.Text.Encoding.UTF8; message.IsBodyHtml = true; client.Send(message); } catch { isSuccess = false; } return isSuccess; } #endregion }????? 短信服務(wù)也和郵件服務(wù)類(lèi)似,通過(guò)實(shí)現(xiàn)接口來(lái)提供服務(wù),那么我們?cè)诒热缯f(shuō)訂單,或者其他的可能會(huì)提醒的地方,就可以通過(guò)自定義實(shí)現(xiàn)不同的格式服務(wù),來(lái)完成
調(diào)用。
?????? 4.5、表現(xiàn)層分析
???? 我們都知道表現(xiàn)層是最終顯示與用戶(hù)交互的功能的,那么我們的表現(xiàn)層是怎么來(lái)調(diào)用服務(wù)層的呢?我們這里的實(shí)例是采用服務(wù)層調(diào)用的方式來(lái)完成。我們這里通過(guò)
定義接口的形式,然后通過(guò)實(shí)現(xiàn)不同的用戶(hù)UI,然后我們通過(guò)展示器來(lái)調(diào)用服務(wù)層,然后將服務(wù)層中的處理結(jié)果返回給展示器,展示器與視圖之間進(jìn)行交互,我們來(lái)看
看表現(xiàn)層的層級(jí)關(guān)系。
????? 大家看到這個(gè)圖請(qǐng)不要詫異,這里的展示器層可能還會(huì)直接訪問(wèn)業(yè)務(wù)邏輯層,也可能直接訪問(wèn)數(shù)據(jù)訪問(wèn)層,這
些都是有可能的,我們需要根據(jù)項(xiàng)目具體的情況去決定。
???? 我們來(lái)看看UI層的視圖代碼:
???? 我們?cè)谝晥D中保持展示器的引用。
/// <summary> /// 定義統(tǒng)一的視圖接口代碼 /// </summary> public interface IView { /// <summary> /// 展示器訪問(wèn)器 /// </summary> B2C.Presenter.IPresenter Presenter { get; set; } }我們來(lái)看看展示器中的部分代碼/// <summary> /// 展示器接口 /// </summary> public interface IPresenter { /// <summary> /// 重新生成視圖 /// </summary> /// <returns></returns> string Review() { return string.Empty; } /// <summary> /// 操作Model /// </summary> /// <typeparam name="T"></typeparam> /// <param name="?"></param> /// <returns></returns> T Controller<T>(T item); }????? 視圖層通過(guò)依賴(lài)注入的方式,或者是屬性注入,還是實(shí)現(xiàn)接口的方式來(lái)實(shí)現(xiàn)展示器的引用,展示器提供接處理用戶(hù)操作的功能,然后根據(jù)處理后的結(jié)果決定是否刷
新視圖。
????? 當(dāng)然如果你這里是借助的MVC框架來(lái)實(shí)現(xiàn)的話(huà),可能控制器中的代碼就要是訪問(wèn)服務(wù)層,或者業(yè)務(wù)邏輯層,數(shù)據(jù)訪問(wèn)層了,可能代碼的形式會(huì)有所不同。其實(shí)我們
還有更好的方式去實(shí)現(xiàn)視圖的展現(xiàn)。比如我們可以讓視圖層與XML文件進(jìn)行綁定的形式,展示器通過(guò)生成XML文件,然后視圖層界面去解析這個(gè)XML文件中的相應(yīng)配
置,來(lái)完成展示,這樣的話(huà),可能視圖層不需要處理單獨(dú)的代碼,而且視圖可以通過(guò)序列化與反序列化的形式,視圖的更改或者操作都可以有系統(tǒng)自動(dòng)完成,而不需要
提供展示器來(lái)完成。當(dāng)然這樣的形式僅限簡(jiǎn)單的應(yīng)用程序時(shí),通過(guò)這樣的形式來(lái)處理可能會(huì)比較靈活。
?????? 4.6、分析總結(jié)
????? 我們上面主要講述了企業(yè)架構(gòu)中的一個(gè)可能的架構(gòu),當(dāng)然這樣的架構(gòu)不是最好的方案,還需要大家多多討論和交流,我只是根據(jù)自己的經(jīng)驗(yàn),結(jié)合一些項(xiàng)目中的一
些問(wèn)題進(jìn)行了總結(jié)之后分析這樣的架構(gòu)模式,還不知道在實(shí)際的姓名中是否能滿(mǎn)足適應(yīng)性和很好的擴(kuò)展性,這個(gè)還有待檢驗(yàn),我這里并沒(méi)有給出完整的代碼實(shí)現(xiàn),只是
給出一種可能的架構(gòu)模式的結(jié)構(gòu),具體的實(shí)現(xiàn)代碼還需要大家自己完善。
????? 我們總結(jié)下我們講述的內(nèi)容:
????? 1、分析了四個(gè)層次中我們對(duì)于設(shè)計(jì)的考慮和各分層中職責(zé)和他們之間的交互,我這里是通過(guò)實(shí)體層來(lái)處理DTO的。
????? 2、舉例給出部分代碼說(shuō)明每個(gè)分層的職責(zé)并且分工要明確。
????? 3、表現(xiàn)層中與其他各層之間可能的交互關(guān)系。
????? 我想通過(guò)上面的可能的模式分析,給大家一個(gè)思路,讓大家通過(guò)這個(gè)思路有個(gè)更多的思考。
五、結(jié)束語(yǔ)
????? 本篇主要講述的是一個(gè)架構(gòu)思路,給出的代碼可能不是完全的,只是給了一個(gè)各層的大概的結(jié)構(gòu),因?yàn)橐獙?shí)現(xiàn)這樣的一個(gè)完整的實(shí)例demo,那是需要非常多的代
碼和要考慮的因素很多,本篇很多內(nèi)容并沒(méi)有涵蓋,不過(guò)我想這樣的方式是不太好的,我后面會(huì)盡量將前面講過(guò)的內(nèi)容,整理出來(lái),以后講述實(shí)例的時(shí)候盡量就是一個(gè)
可以運(yùn)行的demo實(shí)例。
六、系列進(jìn)度
前篇
????? 1、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)系列之--開(kāi)卷有益
????? 2、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)建模[上篇]
????? 3、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)建模[中篇](上)
????? 4、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)建模[中篇](下)
????? 5、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)建模[下篇]
????? 6、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)設(shè)計(jì)規(guī)范與原則[上篇]
????? 7、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)設(shè)計(jì)規(guī)范與原則[下篇]
????? 8、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-設(shè)計(jì)模式[上篇]
????? 9、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-設(shè)計(jì)模式[中篇]
????? 10、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-設(shè)計(jì)模式[下篇]
中篇
?? ? ?11、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-企業(yè)應(yīng)用架構(gòu)
????? 12、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-分層[上篇]
????? 13、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-分層[中篇]
????? 14、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-分層[下篇]
????? 15、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-表現(xiàn)層
????? 16、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-服務(wù)層
????? 17、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-業(yè)務(wù)邏輯層
????? 18、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-數(shù)據(jù)訪問(wèn)層
????? 19、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-組件服務(wù)
????? 20、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-安全機(jī)制
后篇
????? 21、單機(jī)應(yīng)用、客戶(hù)端/服務(wù)器、多服務(wù)、企業(yè)數(shù)據(jù)總線全解析
????? 22、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-單機(jī)應(yīng)用(實(shí)例及demo)
????? 23、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-客戶(hù)端/服務(wù)器(實(shí)例及demo)
????? 24、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-多服務(wù)(實(shí)例及demo)
????? 25、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-企業(yè)數(shù)據(jù)總線(實(shí)例及demo)
????? 26、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-性能優(yōu)化(架構(gòu)瓶頸)
????? 27、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-完整的架構(gòu)方案實(shí)例[上篇]
????? 28、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-完整的架構(gòu)方案實(shí)例[中篇]
????? 29、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-完整的架構(gòu)方案實(shí)例[下篇]
????? 30、系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-總結(jié)及后續(xù)
七、下篇預(yù)告
????? 下一篇我們將會(huì)開(kāi)始講解系統(tǒng)架構(gòu)中的分層-上-中-下進(jìn)行相關(guān)討論及設(shè)計(jì)方案分析,這些都是本人在工作中的經(jīng)驗(yàn)總結(jié),由于本人能力有限,不足之處,
還請(qǐng)大家多多指出。希望大家持續(xù)關(guān)注!
原文鏈接: http://www.cnblogs.com/hegezhou_hot/archive/2010/10/17/1853909.html
轉(zhuǎn)載于:https://my.oschina.net/dtec/blog/43783
總結(jié)
以上是生活随笔為你收集整理的系统架构师-基础到企业应用架构-企业应用架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AgileEAS.NET平台开发实例-药
- 下一篇: VB无所不能之三:VB截获Windows