syuko

Just For Fun。生存,社会秩序,娱乐
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

abstract,virtual,static和工厂的使用问题--另一种解决方案

Posted on 2007-11-13 17:14  syuko  阅读(2029)  评论(20)    收藏  举报
    昨天晚上写了一篇叫做abstract,virtual,static和工厂的使用问题的随笔,写的时候没有设计好就贴出去了。经过了大家的帮忙、提意见,我又重新改了一下,并加入了表现层没有完成的代码。现在将改完的代码和表现层的用户控件的代码一并贴出来起一个抛砖引玉的作用。
    还是同样的问题,和3层架构。
    在业务层(DataBusiness)中原来clsDictCodeBase.cs的代码变成了如下:
   
  1/// <summary>
  2    /// 只有键、值两个字段的数据维护的基类。只能被继承,不能实例化
  3    /// </summary>

  4    public sealed class clsDictCodeBase : ClassBase
  5    {
  6        
  7        
  8
  9        属性
 50
 51        扩展方法的接口
 75
 76        private clsDictCodeBase()
 77        { }
 78
 79        方法
190    }

    这个类以前是个抽象类包含虚方法。现在改成了一个密封类和加入了单件模式。这个类的构造函数改成了私有的,防止被用户直接实例化。同时根据上一版大家提出的意见去掉了部分的try catch语句,并采用了ASTAR Coming Now 的建议加入了扩展事件的接口,只不过这个扩展时间没怎么写。
    原来的业务处理类clsSocietiesMng等都被删除了,使代码的复用性更高。这样当代码表增删改了之后就不用再去维护与之相对应的业务类了。
    原来的控制类clsDictCodeControl也稍微有些变化,代码如下:
 1代码表名称的枚举
17
18    /// <summary>
19    /// 代码表控制类
20    /// </summary>

21    public static class clsDictCodeControl
22    {
23        public static clsDictCodeBase GetControl(dictCodeName codeName)
24        {
25            clsDictCodeBase instance = clsDictCodeBase.GetInstance(); ;
26
27            switch (codeName)
28            {
29                case dictCodeName.Society:
30                    instance.TableName = "DanWei";
31                    instance.PKField = "DanWeiID";
32                    instance.ValueField = "DanWei";
33
34                    return instance;
35                    break;
36                case dictCodeName.Position:
37                    return null;
38                    break;
39                default:
40                    return null;
41                    break;
42            }

43        }

44    }
这个类负责去调用clsDictCodeBase的静态实例化方法创建clsDictCodeBase类的实例。并根据不同的参数给它的表名、字段名赋值。
    clsDictCodeControl这样写是为了表现层使用方便。
    表现层使用的是一个用户控件DictCodeMng.ascx,包含gridview、TextBox、Button等控件,aspx的代码如下:
1<asp:GridView ID="grdShow" runat="server" AutoGenerateColumns="False" OnRowEditing="grdShow_RowEditing">
2                <Columns>
3                    <asp:CommandField HeaderText="修改" ShowEditButton="True" >
4                        <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="60px" />
5                    </asp:CommandField>
6                </Columns>
7            </asp:GridView>
 1<table>
 2                <tr>
 3                    <td style="width: 115px;text-align:right">名称:</td>
 4                    <td style="text-align:left">
 5                        <asp:TextBox ID="txtValue" runat="server"></asp:TextBox></td>
 6                </tr>
 7                <tr>
 8                    <td colspan="2" style="text-align:center">
 9                        <asp:Button ID="btnAdd" runat="server" Text="添加" Width="58px" OnClick="btnAdd_Click" />
10                        <asp:Button ID="btnCancel" runat="server" Text="取消" Width="58px" OnClick="btnCancel_Click" /></td>
11                </tr>
12            </table>
这里面的GridView只有一个控制,并不包含BoundField.所有的BoundField都是动态添加上去的。其后台代码如下:
 1属性
15
16    // 业务处理类
17    private static clsDictCodeBase codeBase = null;
18
19    protected void Page_Load(object sender, EventArgs e)
20    {
21        if (!Page.IsPostBack)
22        {
23            initBusinessClass(_codyType);
24            initGridView();
25            BindGridView();
26        }

27    }

28
29    私有方法

这个用户控件有个CodeType的dictCodeName枚举类型(在后台控制类clsDictCodeControl里定义)的属性,通过这个属性用户控件就知道要去实例化哪个业务类。其实例化方法如下:
1/// <summary>
2    /// 初始化业务类
3    /// </summary>
4    /// <param name="codeName"></param>

5    private void initBusinessClass(dictCodeName codeName)
6    {
7        codeBase = clsDictCodeControl.GetControl(codeName);
8    }

通过实例化的codeBase去操作数据库。然后通过initGridView()方法去初始化GridView的一些属性,并加入绑定列。如果代码表有了变化只需要维护一下clsDictCodeControl类就行了,根本就不用变动其它的地方。
    还有一个地方需要说明的就是根据ASTAR Coming Now 的建议加入的扩展方法。扩展方法在clsDictCodeBase里实现,用的时候代码为:

1codeBase.beginInsert = check;
2                codeBase.InsertRecord(txtValue.Text.Trim());
3                codeBase.afterInsert = done;
4
1private bool check(string value)
2    {
3        return false;
4    }

5
6    private bool done()
7    {
8        return true;
9    }

    就这样整个解决方案就完整了,从业务层到表现层。符合了微软推崇的组件式的开发思想。