码迷,mamicode.com
首页 > 其他好文 > 详细

背单词软件-设计于实现

时间:2014-08-30 17:42:49      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:winform   style   blog   http   color   os   io   strong   ar   

2014-08-28

三层结构

  数据访问层

  业务逻辑层

  表现层

数据结构

技术要点

经验于教训

参考

三层结构


 返回

三层结构优点:职责明确,易于理解,提高代码重用率,便于改动。

三层结构缺点:上层依赖下层,下层修改,上层也得相应修改。

bubuko.com,布布扣

图1 Solution

从图1可知,软件是三层结构,分别是表现层、业务逻辑层、数据访问层。三层结构都是上层调用下层:表现层->业务逻辑层->数据访问层,表现层->数据访问层亦可。

数据访问层 

数据访问层提供对永久层数据(比如:文件,数据库)的简单操作(增删改查)。

注意:这一层操作逻辑一定要简单,便于业务逻辑层调用。

图2是TaskDataAccess的方法和属性,只有对xml文件增删改查、创建、保存操作

bubuko.com,布布扣

图2 TaskDataAccess

业务逻辑层

如果数据访问层方法的比较简单,那么数据访问层的方法相对复杂,粒度更大,加入更多判断和相关操作。

下面是TaskDataControl.cs的主要的公共方法:

bubuko.com,布布扣
 1 public void Refresh();
 2 public List<string> ReciteUnitNow();
 3 public void AutoChangeRecitePeriod(string unitName, DateTime dt);
 4 public void RedoRecitePeriod(string unitName);
 5 public void RedoReciteUnit(string unitName);
 6 public void ReDoFilterUnit(string unitName);
 7 public void CompleteRecitePeriod(string unitName);
 8 public void CompleteReciteUnit(string unitName);
 9 public void DeleteUnit(string unitName);
10 public void FilterUnit(string unitName);
11 public void ReciteUnit(string unitName);
View Code

 

表现层

表现层包括界面设计以及状态。以frmReciteWord_Task为例,它包括界面frmReciteWord_Task、幕后代码,还有TaskDiplay.cs。其中,TaskDisplay.cs主要负责界面状态,把它分离出来,主要是为了方便理解,和重用。

数据结构


返回

永久层

文件TaskFile.xml

bubuko.com,布布扣
 1 <?xml version="1.0"?>
 2 <Units>
 3   <Unit Name="Lession01" UnitStatus="Complete" />
 4   <Unit Name="Lession02" UnitStatus="Start">
 5     <Detail Period="2" PeriodStatus="Complete" CurrentReciteTime="8/27/2014 11:04:26 PM" />
 6   </Unit>
 7   <Unit Name="Lession03" UnitStatus="Start">
 8     <Detail Period="2" PeriodStatus="Start" CurrentReciteTime="8/27/2014 11:04:26 PM" />
 9   </Unit>
10   <Unit Name="Lession04" UnitStatus="Start">
11     <Detail Period="0" PeriodStatus="Start" CurrentReciteTime="8/27/2014 11:01:26 PM" />
12   </Unit>
13   <Unit Name="Lession05" UnitStatus="Start">
14     <Detail Period="0" PeriodStatus="Start" CurrentReciteTime="8/27/2014 09:01:26 PM" />
15   </Unit>
16   <Unit Name="Lession06" UnitStatus="Filter" />
17   <Unit Name="Lession07" UnitStatus="Raw" />
18 </Units>
View Code

我们可以看到,永久层的属性有:Name, UnitStatus, Period, PeriodStatus, CurrentReciteTime

业务逻辑层

文件TaskDataControl.cs

bubuko.com,布布扣

图3 Task Business data constructor

业务逻辑层属性有:Name, UnitStatus, Period, PeriodStatus, CurrentReciteTime, Priority, NextReciteTime。其中,Priority, NextReciteTime是计算出来的。

在这些属性中,UnitStatus和PeriodStatus比较相似,他们的值,我用枚举一一列出来了:

1 enum EnumTaskUnitStatus { Start, Complete, Raw, Filter }
2 enum EnumTaskPeriodStatus { Start, Complete }

我们可以看到两个状态中都有Start和Complete。因为要把课文中单词永久记住,需有多个周期的记忆、遗忘。UnitStatus的Start和Complet指的是开始学习,到最后结束;而PeriodStatus的Start和Complete只当前周期的开始结束。

注意:数据结构中,对某个属性理解比较模糊时,一定要停下来思考清楚。清晰的设计,带来轻松的实现。

当然,永久层的数据结构和业务逻辑层的数据结构不必完全一一对应,视实际情况而定。 

难点与解决方案


 返回

Recite的自动播放功能

当时想用线程实现,然后在线程中直接更改winForm中控件的值来更改winForm的界面显示。但这样做会抛出异常:

Cross-thread operation not valid: Control accessed from a thread other than the trhead it was created on. 

解决方案是通过control.invoke来更改控件的值。具体原理 横刀天笑 写的博客 WinForm二三事:

WinForm二三事(一)消息循环

WinForm二三事(一)补遗

WinForm二三事(二)异步操作

WinForm二三事(三)Control.Invoke&Control.BeginInvoke

Recite的播放暂停功能

上面提到自动播放是通过thread实现的,原本暂停功能想通过thread自带方法suspend()实现,但高版本net framework mark这个方法depreciated。因此,另找出路,用AutoResetEvent类来通知thread wait or contiune。看代码示例:

bubuko.com,布布扣
 1     public partial class Form1 : Form
 2     {
 3         System.Windows.Forms.Timer tm = new System.Windows.Forms.Timer();
 4 
 5         //through autoEvent notify a thread waiting or continue
 6         AutoResetEvent autoEvent = new AutoResetEvent(false);        
 7 
 8         public Form1()
 9         {
10             InitializeComponent();
11             ProgressBar.CheckForIllegalCrossThreadCalls = false;
12 
13             
14             tm.Interval = 1;
15             tm.Tick += new EventHandler(tm_Tick);            
16         }
17 
18         void tm_Tick(object sender, EventArgs e)
19         {
20             autoEvent.Set(); //allow waiting thread proceed    
21         }
22         
23 
24         //method for thread   
25         private void DoWork()
26         {
27             while (progressBar1.Value < progressBar1.Maximum)
28             {
29                 progressBar1.PerformStep();
30                 System.Threading.Thread.Sleep(100);
31                 autoEvent.WaitOne();  //Block current thread until autoEvent.Set()    
32             }
33         }
34 
35         private void btnStart_Click(object sender, EventArgs e)
36         {
37             tm.Start();
38 
39             Thread t = new Thread(DoWork);
40             t.Start();
41             t.Suspend();
42         }
43 
44         private void btnSuspend_Click(object sender, EventArgs e)
45         {
46             tm.Stop();
47         }
48 
49         private void btnResume_Click(object sender, EventArgs e)
50         {
51             tm.Start();
52         }   
53     }
View Code

窗口之间传递数据

这里主要通过两种方法:

  • 通过公开的属性
  • 单独设个类,通过静态set和get方法 

设置信息处理

设置信息见上一篇设置功能,一般可以存放在xml配置文件中。但为了程序更简单,把这些信息放在注册表中。set,get注册表的静态方法都放在Utility.cs文件中。

经验于教训


 返回

参考

背单词软件-设计于实现

标签:winform   style   blog   http   color   os   io   strong   ar   

原文地址:http://www.cnblogs.com/Ming8006/p/3941928.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!