首页 > 编程开发 > Objective-C编程 >
-
学习WF系列(7)改善登陆程序上
1. 温故而知新
还记得我们在一步一步学WF系列(四)中写的登陆程序么?如果忘记了,那就回去看看。
在这一节中,让我们去改善我们的登录程序。
最近一直在忙着找工作的事情,所以发文慢了些,还望各位见谅。
3. 引出话题
我之前一直在强调,工作流负责的是一个宏观工作,我们应该把他与整体设计外的,那些边边角角的细节隔离在外面。
我最近在这个系列的同时,还在写一个《重温设计模式》的系列文章,因此特别要强调针对接口编程的重要性。
好,从现在开始步入正题。
4. 回顾登录
让我们回顾一下原有的登陆程序,在原有的登陆项目中,我们把所有的工作都杂糅在了工作流中。
让我们看看我们曾经丑陋的代码:
Workflow2.cs:
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
MessageBox.Show("用户名和密码不能为空");
}
private void Validate(object sender, ConditionalEventArgs e)
{
e.Result = this.userName.Equals("admin") && this.userPassword.Equals("admin");
}
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
MessageBox.Show("登陆成功");
}
private void codeActivity3_ExecuteCode(object sender, EventArgs e)
{
MessageBox.Show("用户名和密码不正确");
}
我想,当时也许有人会有这个疑问,楼主,你这不是骗人么?用不用工作流有什么呢?你不过是把原有的应该在Winform后台写的东西拿到了工作流中去写罢了。
好,我们从现在开始改善我们这段丑陋的代码。
5. 登录设计
让我们先来想想我们在登录时的步骤,包括我们的做的和系统做的:
好,那么我们想,工作流负责的应该是一个宏观的过程,那么我们要把具体的细节给抽取出来,究竟什么是具体细节呢?
A. 用户的验证过程。(可能是连接数据库,可能是连接文件验证)
B. 反馈给客户的反馈信息。(可能是Response.Write,可能是MessageBox.Show)
好,抽取出了这两条,让我们想,是什么触发了这个工作流程,是我们点击登陆按钮的一刹那:
那么我们应该用一个事件去监听我们的登录按钮事件,当我们点击登录时便触发工作流。
分析结束,那就让我们看看我们的建模图:
由于本人的Visio功力实在有限,所以就用画图来画这些图了,我一定抓紧时间去练习Visio。
图画的不太好,我再来解释一下:
A. 用户首先输入用户名,密码,然后点击登录。
B. 这个时候触发了工作流的事件,并且向事件中传入我们所输入的信息。
C. 工作流根据我们所传入的信息去请求验证的接口,执行验证的代码。
D. 根据返回的结果,然后去请求相应的响应接口。
E. 最后将结果返回给用户。
分析结束,我们看到,这里面有个很重要的东西,就是工作流和外部的交互,好,那就让我们在改善登录程序前,先学习两个重要的活动。
6. HandlerExternalEvent
HandlerExternalEvent是我们接触的第一个事件类型的活动。事件类型就是通过某个事件才可以触发的活动。
我长话短说,这个活动的作用是在工作流的外部去调用工作流内部的方法,即HandlerExternalEvent的事件。
我在这里做一个小例子,然后结合代码为大家讲解。
首先让我们添加一个HandlerExternalEvent活动:
然后让我们新建一个类库,类库中包含一个接口,来做工作流和外部程序的一个交互:
namespace Interface
{
[ExternalDataExchange]
public interface IEvent
{
event EventHandler<ExternalDataEventArgs> MyEvent1;
}
}
这段代码,我们注意三个点:
A. ExternalDataExchange:将接口标记为本地服务接口,具有该特性才能被工作流识别。
B. 接口内部事件:工作流在内部将自身绑定到该事件,用户在外部通过该事件触发工作流内部方法。
C. ExternalDataEventArgs:标识使用HandlerExternalEventActivity活动引发事件时传递的参数。
好,接下来我们通过属性窗口将该事件绑定到工作流的HandlerExternalEventActivity中:
然后我们在外部去调用这个事件,看整个项目的完整代码:
Workflow1.cs:
public sealed partial class Workflow1 : SequentialWorkflowActivity
{
public Workflow1()
{
InitializeComponent();
}
private void handleExternalEventActivity1_Invoked(object sender, ExternalDataEventArgs e)
{
MessageBox.Show("Success");
}
}
Winform1.cs:
public partial class Form1 : Form,IEvent
{
private WorkflowRuntime runtime;
private ExternalDataExchangeService service;
private WorkflowInstance instance;
public Form1()
{
InitializeComponent();
runtime = new WorkflowRuntime();
service = new ExternalDataExchangeService();
runtime.AddService(service);
service.AddService(this);
runtime.StartRuntime();
}
private void button1_Click(object sender, EventArgs e)
{
instance = runtime.CreateWorkflow(typeof(WorkflowConsoleApplication7.Workflow1));
instance.Start();
ExternalDataEventArgs args = new ExternalDataEventArgs(instance.InstanceId);
MyEvent1(null, args);
}
#region IEvent 成员
public event EventHandler<ExternalDataEventArgs> MyEvent1;
#endregion
}
7. CallExternalMethod
与上面的活动相反,这个活动的作用是通过这个事件去调用外部的代码。
同样,我们用代码来说话:
接下来,我们同样来新建一个类库,包含一个接口用来和外部程序进行交互:
不同的是,在HandlerExternalEvent的接口中是事件,而这个是方法:
namespace CallMethod
{
[ExternalDataExchange]
public interface ICallExternalMethod
{
void CallExternalMethod();
}
}
这个和上面都是一个道理的,我就不多做解释了:
让我们直接看代码吧:
Winform2.cs:
public partial class Form2 : Form,ICallExternalMethod
{
private WorkflowRuntime runtime;
private ExternalDataExchangeService service;
private WorkflowInstance instance;
public Form2()
{
InitializeComponent();
runtime = new WorkflowRuntime();
service = new ExternalDataExchangeService();
runtime.AddService(service);
service.AddService(this);
runtime.StartRuntime();
}
#region ICallExternalMethod 成员
public void CallExternalMethod()
{
MessageBox.Show("调用了这个方法");
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
instance = runtime.CreateWorkflow(typeof(WorkflowConsoleApplication7.Workflow2));
instance.Start();
}
}
8. 写在后面
本来想在这篇文章中完成对我们之前登录的改造,但是文章太长了大家好像都不太爱看,于是就还是分开写吧。
我们已经学习了如何让工作流和外部程序进行交互,那么我们大家就试着用这个去改善一下工作流吧?
你能么?
系列文章:
学WF系列(一)——Hello world开始
学WF系列(二)——工作流与Visual Studio
学WF系列(三)
学WF系列(四)——工作流模拟登陆
学WF系列(五)——工作流模拟猜数游戏
学WF系列(六)——工作流模拟投票项目
学WF系列(八)——改善登录程序(下)
好,我们从现在开始改善我们这段丑陋的代码。
5. 登录设计
让我们先来想想我们在登录时的步骤,包括我们的做的和系统做的:
好,那么我们想,工作流负责的应该是一个宏观的过程,那么我们要把具体的细节给抽取出来,究竟什么是具体细节呢?
A. 用户的验证过程。(可能是连接数据库,可能是连接文件验证)
B. 反馈给客户的反馈信息。(可能是Response.Write,可能是MessageBox.Show)
好,抽取出了这两条,让我们想,是什么触发了这个工作流程,是我们点击登陆按钮的一刹那:
那么我们应该用一个事件去监听我们的登录按钮事件,当我们点击登录时便触发工作流。
分析结束,那就让我们看看我们的建模图:
由于本人的Visio功力实在有限,所以就用画图来画这些图了,我一定抓紧时间去练习Visio。
图画的不太好,我再来解释一下:
A. 用户首先输入用户名,密码,然后点击登录。
B. 这个时候触发了工作流的事件,并且向事件中传入我们所输入的信息。
C. 工作流根据我们所传入的信息去请求验证的接口,执行验证的代码。
D. 根据返回的结果,然后去请求相应的响应接口。
E. 最后将结果返回给用户。
分析结束,我们看到,这里面有个很重要的东西,就是工作流和外部的交互,好,那就让我们在改善登录程序前,先学习两个重要的活动。