• 走向.NET架构设计—第三章—分层设计,初涉架构(后篇)


    走向.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; }
    }

       这个接口会被ASPXWeb Form来实现。

      下面我们就来创建一个ProductListPresenter来连接ViewServicePresenter负责把数据从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的实例,并且我们通过StructureMapObjectFactory.GetInstance方法得到了一个门户的ProductServiceDefault页面把任何对他的事件的调用委托给了Presenter,也就是说,我们基本上不在Default的页面代码后面做什么逻辑处理,这一切都放在Presenter里面。 

          最后我们设计的结构就很利于测试和维护,也有很强的扩展性。 

      本篇(前。中,后篇)就到这里了,还是那句话:把三篇连在一起看,多琢磨下,有什么问题大家可以留言!多谢支持! :)

     

  • 相关阅读:
    Android网络框架之Retrofit + RxJava + OkHttp 变化的时代
    网易与Google合作发布开源UI自动化测试方案 牛逼:Google 方面评价,这可能是目前世界上最好的 Android 游戏自动化测试方案。
    GitHub上受欢迎的Android UI Library
    推荐一些socket工具,TCP、UDP调试、抓包工具 (转载)
    pytest 一个测试类怎样使用多种fixture前置方法
    Appium服务器初始化参数(Capability)
    pytest执行用例:明明只写了5个测试用例, 怎么收集到33个!?
    解决VirtualBox 运行时报内存不能written
    VirtualBox 虚拟机怎样设置共享文件夹
    简单通俗讲解 android 内存泄漏
  • 原文地址:https://www.cnblogs.com/yanyangtian/p/1864087.html
Copyright © 2020-2023  润新知