业精于勤

导航

设计模式:Model View Presenter(MVP)

刚看了MSDN上介绍的设计模式MVP,总体感觉是它有点像MVC, 我觉得MVP主要解决的问题是UI控件重用的问题,将界面层UI涉及的业务逻辑减至最少,这样更易实现项目C/S,B/S的交换开发,因为他们共用同一的业务层。
但是这个示例有点不足的是它的业务层与控件抽象DTO层也相关,使得业务层比较复杂,业务层应该只与表示层相关联。
他原来的系统架构是这样的:

Web.UI 界面层,Presentation表示层(像业务外观层),DTO控件抽象接口层,Web.Controls控件层,Task 业务层,DataAccess数据访问层,Domain数据服务层(主要是业务数据对象)。
应该将业务层与DTO的引用断开,将DTO中的CustomerDTO对象删除,且替换为Domain的ICustomer。使得在整个应用中业务数据对象都使用Domain层的。
修改后的 MVP.Task.ICustomerTask:
  public interface ICustomerTask
    {
        IList<ICustomer> GetCustomerList();
        ICustomer GetDetailsForCustomer(int customerId);
    }
修改后的 MVP.Task.CustomerTask:
  public class CustomerTask : ICustomerTask
    {
        private readonly ICustomerMapper customerMapper;

        public CustomerTask() : this(new CustomerMapper())
        {
        }

        public CustomerTask(ICustomerMapper customerMapper)
        {
            this.customerMapper = customerMapper;
        }

        public IList<ICustomer> GetCustomerList()
        {
            return customerMapper.GetAllCustomers();
              //  new LookupCollection(new CustomerToLookupConverter().ConvertAllFrom(customerMapper.GetAllCustomers()));
        }

        public ICustomer GetDetailsForCustomer(int customerId)
        {
            ICustomer customer = customerMapper.FindById(customerId);
            return customer;
            
        }
    }
将Converters文件夹下的三个转换文件移植到Presentation。
修改表示层:
namespace MVP.Presentation
{
    public class ViewCustomerPresenter
    {
        private readonly IViewCustomerView view;
        private readonly ICustomerTask task;

        public ViewCustomerPresenter(IViewCustomerView view) : this(view, new CustomerTask()) {}

        public ViewCustomerPresenter(IViewCustomerView view, ICustomerTask task)
        {
            this.view = view;
            this.task = task;
        }

        public void Initialize()
        {
            this.GetLookupCollection().BindTo(view.CustomerList);
        }
        private ILookupCollection GetLookupCollection()
        {
            IList<ICustomer> oCustomers = task.GetCustomerList();
            IList<ILookupDTO> oLookup = new CustomerToLookupConverter().ConvertAllFrom(oCustomers);
            return new LookupCollection(oLookup);
        }
        public void DisplayCustomerDetails()
        {
            int? customerId = SelectedCustomerId;

            if (customerId.HasValue)
            {
                ICustomer customer = task.GetDetailsForCustomer(customerId.Value);
                UpdateViewFrom(customer);
            }
        }

        private int? SelectedCustomerId
        {
            get
            {
    string selectedId = view.CustomerList.SelectedItem.Value;
    
                if (String.IsNullOrEmpty(selectedId)) return null;

                int? id = null;

                try
                {
                    id = int.Parse(selectedId.Trim());
                }
                catch (FormatException) {}

                return id;
            }
        }

        private void UpdateViewFrom(ICustomer customer)
        {
            view.CompanyName = customer.CompanyName;
            view.ContactName = customer.ContactName;
            view.ContactTitle = customer.ContactTitle;
            view.Address = customer.Address;
            view.City = customer.City;
            view.Region = customer.Region;
            view.Country = customer.Country.Name;
            view.Phone = customer.Phone;
            view.Fax = customer.Fax;
            view.PostalCode = customer.PostalCode;
        }
    }

参考:http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/MVP.mspx?mfr=true

posted on 2006-11-22 20:01  勤能补拙  阅读(1037)  评论(2编辑  收藏  举报