系列文章导航:
.NET初学者架构设计指南(一)Hello world的时代
.NET初学者架构设计指南(二)OO设计初次见面
.NET初学者架构设计指南(三)设计模式
.NET初学者架构设计指南(四)Model-View-Controller
在示例程序里,当主画面打开时,会建立三个Action,并且绑定相应的界面控件。请看MainWin的Form1_Load方法:
Code
private void Form1_Load(object sender, System.EventArgs e)
{
//退出应用程序
BaseAction exitAction = ActionFactory.CreateAction(1000);
exitAction.Init(menuItem7);
//打开用户缴费的界面
BaseAction openPayMoneyAct = ActionFactory.CreateAction(1001);
openPayMoneyAct.Init(toolBarButton1);
openPayMoneyAct.Init(menuItem5);
openPayMoneyAct.Init(this.treeView1.Nodes[0].Nodes[0]);
//打开资费变更的界面
BaseAction openChangePriceAct = ActionFactory.CreateAction(1002);
openChangePriceAct.Init(toolBarButton2);
openChangePriceAct.Init(menuItem6);
openChangePriceAct.Init(treeView1.Nodes[0].Nodes[1]);
//openChangePriceAct.IsVisible = false;
//openChangePriceAct.Enabled = false;
}
在用户缴费和资费变更的界面上,也是用相似的方式实现了行为的控制。请看PayMoney和ChangePrice的构造函数,他们分别建立了自己需要的行为,并且和按钮进行绑定。
在Action的Execute方法中,收集视图上的输入,调用业务对象进行工作。然后再把工作的结果展现在视图上。下面是PayMoneyAction的Execute方法,他实现了缴费功能:
Code
public override void Execute()
{
//更新视图属性,把视图元素的值更新到属性里面
BaseView view = MainWin.GetInstance().GetActiveView();
view.UpdateAttributes();
//得到界面上的电话号码和缴费金额
string phone_no = view.GetAttribute("phone_no").ToString();
string money_amount = view.GetAttribute("money_amount").ToString();
//调用业务对象进行缴费
try
{
User user = User.GetUserByPhoneNo(phone_no);
Account account = user.GetAccount();
account.Pay(float.Parse(money_amount));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
//向界面发出成功消息
MessageBox.Show("缴费成功 :)");
//把界面清空
view.SetAttribute("phone_no", "");
//根据视图的属性,更新视图界面
view.UpdateView();
}
现在我们实现了一个前端控制器的最简单的示例。令人不满意的是,其中有很多硬编码:在主窗体上的控件都是手工拖放上去的,行为也要手工定义,然后与控件进行绑定;并且在ActionFactory和ViewFactory中,行为和视图的建立也是用硬编码实现的。下面我们就来做一些事情,消除程序里的硬编码。
我们需要定义一个表,名叫ACTION_LIST,用来表示系统中所有的行为:
ActionFactory可以根据传入的ID编号查找到对应的类型,然后使用反射的方式建立需要的实例。如果我们需要对行为进行权限控制,可以再建立一个“访问控制表”(Access
Control
List,简称ACL),在这个访问控制表中记录用户和行为的访问限制关系。ActionFactory在建立Action实例之后,需要参照这个ACL对Action的Enabeld属性和IsVisible属性进行设置。只要维护一个ACL,就能实现最灵活的行为权限控制。
再建立一个类似的表:VIEW_LIST,用来定义所有的视图。ViewFactory可以根据这个表创建需要的视图实例: