走向.NET架構設計—第三章—分層設計,初涉架構(後篇)
前言:本篇主要是接着前兩篇文章繼續講述!
本篇的議題如下: 4. 資料通路層設計 5. 顯示層設計 6. UI層設計
4. 資料通路層設計
資料通路層,這塊要說的不多。但是要澄清一點:資料通路不一定就是通路資料庫,雖然多數的情況下,我們确實把資料存儲在資料庫中。
這裡我們用資料庫存儲資料,并且用Linq To Sql來進行資料通路操作。
下面我們就來實作資料操作的一些代碼:
代碼
public class ProductRepository : IProductRepository
{
public IList<Model.Product> FindAll()
{
var products = from p in new ShopDataContext().Products
select new Model.Product
{
Id = p.ProductId,
Name = p.ProductName,
Price = new Model.Price(p.RRP, p.SellingPrice)
};
return products.ToList();
}
}
5. 顯示層設計
我們這裡用Model-View-Presenter模式把顯示邏輯從UI層中分離出來,成為顯示層。其實這樣做的好處:友善單元測試,同時也讓我們可以換不同的View來顯示,例如我們可以換成aspx的頁面顯示,也可以用WinForm來顯示。關于MVP的詳細知識,我會在後續的文章中後慢慢的講述,本篇隻是”初涉架構”----相當于把後續文章的知識都提了一下。
通過看代碼來講述。我們在ASPPatterns.Chap3.Layered.Presentation項目加入一個接口類:IProductListView.
public interface IProductListView
{
void Display(IList<ProductViewModel> Products);
Model.CustomerType CustomerType { get; }
string ErrorMessage { set; }
}
這個接口會被ASPX的Web Form來實作。
下面我們就來建立一個ProductListPresenter來連接配接View和Service。Presenter負責把資料從service拿來,然後交給View去顯示。代碼如下:
public class ProductListPresenter
{
private IProductListView _productListView;
private Service.ProductService _productService;
public ProductListPresenter(IProductListView ProductListView, Service.ProductService ProductService)
_productService = ProductService;
_productListView = ProductListView;
}
public void Display()
ProductListRequest productListRequest = new ProductListRequest();
productListRequest.CustomerType = _productListView.CustomerType;
ProductListResponse productResponse = _productService.GetAllProductsFor(productListRequest);
if (productResponse.Success)
{
_productListView.Display(productResponse.Products);
}
else
_productListView.ErrorMessage = productResponse.Message;
}
這樣實作之後,我們現在就可以編寫一些測試的代碼來測試資料取的是否正确,此時我們不一定非得用頁面的顯示才知道資料的正确性。而且這樣實作的好處之前也提過:我們可以把資料給WPF的界面顯示,或者給WinForm的界面顯示。
6. UI層設計
最後不管怎麼樣,我們還是需要顯示一下資料的。
界面如下:
ASPX頁面的代碼如下:
public partial class _Default : System.Web.UI.Page, IProductListView
private ProductListPresenter _presenter;
protected void Page_Init(object sender, EventArgs e)
_presenter = new ProductListPresenter(this, ObjectFactory.GetInstance<Service.ProductService>());
this.ddlCustomerType.SelectedIndexChanged += delegate { _presenter.Display();};
protected void Page_Load(object sender, EventArgs e)
if (Page.IsPostBack != true)
_presenter.Display();
public void Display(IList<ProductViewModel> Products)
rptProducts.DataSource = Products;
rptProducts.DataBind();
public CustomerType CustomerType
get { return (CustomerType)Enum.ToObject(typeof(CustomerType), int.Parse(this.ddlCustomerType.SelectedValue) ); }
public string ErrorMessage
set { lblErrorMessage.Text = String.Format("<p><strong>Error</strong><br/>{0}<p/>", value); }
希望大家看到上面一堆代碼不要暈,下面就通過一個圖來講述一下整個流程:
Default
Page在頁面的初始化的時候建立一個ProductListPresenter的執行個體,并且我們通過StructureMap的ObjectFactory.GetInstance方法得到了一個門戶的ProductService。Default頁面把任何對他的事件的調用委托給了Presenter,也就是說,我們基本上不在Default的頁面代碼後面做什麼邏輯處理,這一切都放在Presenter裡面。
最後我們設計的結構就很利于測試和維護,也有很強的擴充性。
本篇(前。中,後篇)就到這裡了,還是那句話:把三篇連在一起看,多琢磨下,有什麼問題大家可以留言!多謝支援! :)
本文轉自yanyangtian51CTO部落格,原文連結:
http://blog.51cto.com/yanyangtian/412165
,如需轉載請自行聯系原作者