您可能想看看MVP模式。由于您可能正在使用WebForms,因此很难迁移到ASP.Net MVC,但您可以很容易地将MVP实现到现有的应用程序中。
在基本层面上,你会移动所有的业务逻辑到有一种观点认为代表了某种界面的演示类:
public class SomePresenter
{
public ISomeView View{get; set;}
public void InitializeView()
{
//Setup all the stuff on the view the first time
View.Name = //Load from database
View.Orders = //Load from database
}
public void LoadView()
{
//Handle all the stuff that happens each time the view loads
}
public Int32 AddOrder(Order newOrder)
{
//Code to update orders and then update the view
}
}
你需要定义你的界面按住你要的原子类型显示:
public interface ISomeView
{
String Name {get; set;}
IList<Order> Orders{get; set;}
}
一旦那些被定义,你现在可以简单地实现你的表单接口:
public partial class SomeConcreteView : System.Web.UI.Page, ISomeView
{
public SomePresenter Presenter{get; set;}
public SomeConcreteView()
{
Presenter = new SomePresenter();
//Use the current page as the view instance
Presenter.View = this;
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Presenter.InitializeView();
}
Presenter.LoadView();
}
//Implement your members to bind to actual UI elements
public String Name
{
get{ return lblName.Text; }
set{ lblName.Text = value; }
}
public IList<Order> Orders
{
get{ return (IList<Order>)ordersGrid.DataSource; }
set
{
ordersGrid.DataSource = value;
ordersGrid.DataBind();
}
}
//Respond to UI events and forward them to the presenter
protected virtual void addOrderButton_OnClick(object sender, EventArgs e)
{
Order newOrder = //Get order from UI
Presenter.AddOrder(newOrder);
}
}
正如你所看到的,你背后的代码现在非常简单,所以代码重复并不是什么大不了的事情。由于核心业务逻辑全部封装在某个DLL中,因此不必担心功能不同步。演示者可以在多个视图中使用,因此您可以高度重用,并且只要遵守合同,就可以自由更改UI,而不会影响业务逻辑。
这种模式也适用于用户控件,因此您可以根据需要获得模块化。这种模式也开辟了可能性,为您单元测试你的逻辑,而不必运行一个浏览器:)
的patterns and practices组有一个很好的实现这个:WCSF
不过,你不必使用他们的框架来实施这种模式。我知道这可能起初看起来有点令人生畏,但它会解决许多你遇到的问题(在我看来)。