C#版的组合查询+模板方法

    在第一次机房收费系统的时候就发现很多相似的窗体,很多重复的代码,那时遇见相似的功能自己还会窃喜,因为不用再次敲了,直接ctrl+c和ctrl+v然后稍加改动就可以了。但是当第二次重构的时候,学习了设计模式,也听同学和师父们讲了很多,重构的时候需要加设计模式,来减少代码的冗余等,现在自己亲身经历,也要感受一下设计模式的神奇所在。

考卷VS组合查询

    一些组合查询的窗体(操作员工作记录,学生上机记录查询,学生基本信息维护,金额返还信息查询)都是相似的,只是对应查询的表不同,这时候就想到了设计模式中的模板方法——考生试卷的问题,大话设计中介绍的模板方法是通过相同的考卷不同的学生不同的答案来生动介绍的。大同小异,现在几个组合查询的窗体也是相同的,不同的是窗体查询所需要的表不同,选择的字段不同罢了。所以使用模板方法是最好的选择了。首先来介绍一下模板方法。

模板方法

定义

    一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

我的理解

    概念说的比较抽象,结合组合查询窗体来理解一下。就是说先把各个窗体中相同的东西全部提取出来,写在父类中,而将各个窗体独特的东西采用虚方法的方式也写在父类中,然后创建子类继承父类,再在子类中通过重写的方法把不同的内容写出来,就可以实现了。

组合查询实现过程

窗体部分

1、先创建父窗体,各个窗体共同的部分都抽象提取出来。

C#版的组合查询+模板方法_第1张图片

2、再创建继承的窗体,即继承父窗体。

添加窗体——Windows Forms继承的窗体——选择想要继承的父窗体,如下

C#版的组合查询+模板方法_第2张图片

代码部分

实体是需要传递数据的,代码同样少不了实体部分,这里就不详细介绍了。

1、父窗体中

模板方法父类中的虚方法,判断窗体中控件是否为空,就不一一啰嗦了。

<span style="font-family:KaiTi_GB2312;font-size:18px;">        protected virtual void ToDgv(Entity.GroupCheck groupcheck)//通过实体将不同的内容显示在各个窗体中
        {

        }
        public virtual string ToEnglish(string combo)//将汉字转换成数据库识别的形式
        {
            return "";
        }
        protected virtual string GetdbName()//获得数据库名字
        {
            return "";
        }</span>

2、子类中的代码(以查询操作员工作记录为例)

<span style="font-family:KaiTi_GB2312;font-size:18px;">        private void frmWorkLog_Load(object sender, EventArgs e)
        {
            frmWorkLog  frm = new frmWorkLog();
            frm.Text = "工作记录查询";
            //操作符
            combFeild1.Items.Add("教师");
            combFeild1.Items.Add("注册时间");
            combFeild1.Items.Add("注册日期");
            combFeild1.Items.Add("注销时间");
            combFeild1.Items.Add("注销日期");
            combFeild1.Items.Add("机器名");

            combFeild2.Items.Add("教师");
            combFeild2.Items.Add("注册时间");
            combFeild2.Items.Add("注册日期");
            combFeild2.Items.Add("注销时间");
            combFeild2.Items.Add("注销日期");
            combFeild2.Items.Add("机器名");

            combFeild3.Items.Add("教师");
            combFeild3.Items.Add("注册时间");
            combFeild3.Items.Add("注册日期");
            combFeild3.Items.Add("注销时间");
            combFeild3.Items.Add("注销日期");
            combFeild3.Items.Add("机器名");
        }
<span style="font-family:KaiTi_GB2312;">        </span>public override string ToEnglish(string combo)//重写虚方法,<span style="font-family:KaiTi_GB2312;">将汉字换成数据库能识别的字母</span>
        {
            switch (combo )
            {
                case "教师":
                    return "UserID";
                case "注册时间":
                    return "LoginTime";
                case "注册日期":
                    return "LoginDate";
                case "注销时间":
                    return "LogoutTime";
                case "注销日期":
                    return "LogoutDate";
                case"机器名":
                    return "Computer";
                default :
                    return "";
            }
        }
        protected override  string GetdbName()//重写,表示需要查询的是worklog表
        {
            return "Worklog";
        }
        protected override void ToDgv(Entity .GroupCheck groupcheck)//重写,显示查询结果
        {
            DataTable dt = new DataTable();
            jfChargeSystemFacade.GroupCheck fac = new jfChargeSystemFacade.GroupCheck();//调用外观的方法
            dt = fac.GroupCheckFacade(groupcheck);
            
<span style="font-family:KaiTi_GB2312;">            </span>dataGridView1.DataSource = dt;
            dataGridView1.Columns[0].HeaderText = "用户名";
            dataGridView1.Columns[1].HeaderText = "水平";
            dataGridView1.Columns[2].HeaderText = "注册时间";
            dataGridView1.Columns[3].HeaderText = "注销时间";
            dataGridView1.Columns[4].HeaderText = "注销日期";
            dataGridView1.Columns[5].HeaderText = "注册日期";
            dataGridView1.Columns[6].HeaderText = "机器名";
            dataGridView1.Columns[7].HeaderText = "状态";
            dataGridView1.Refresh();

        }</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;">Facede观:</span>  public DataTable GroupCheckFacade(Entity.GroupCheck  GC)
        {
            jfChargeSystemBLL.GroupCheck  GKStu = new jfChargeSystemBLL.GroupCheck();
            DataTable dt = GKStu.GCheck (GC);
            return dt;
        }
<span style="font-family:KaiTi_GB2312;">B层:public DataTable GCheck(Entity .GroupCheck GKstudent)
        {
            jfChargeFactory.GroupCheck GKfactory = new jfChargeFactory.GroupCheck();
            jfChargeSystemIDAL.IGroupCheck IGKstu;
            IGKstu = GKfactory.GCheck();
            DataTable dt = IGKstu.GroupCheck(GKstudent);
            return dt;
        }
D层:public DataTable GroupCheck(Entity.GroupCheck GKstudent)
        {
            DataTable dt = new DataTable();
            string sql = "GroupCheck";//存储过程
            SqlParameter[] paras = new SqlParameter[]
            {               
                new SqlParameter ("@Field1", GKstudent.CobField ),
                new SqlParameter ("@Field2", GKstudent.CobField2 ),
                new SqlParameter ("@Field3", GKstudent.CobField3 ),
                new SqlParameter ("@Operator1", GKstudent.cobOperator1  ),
                new SqlParameter ("@Operator2", GKstudent.cobOperator2  ),
                new SqlParameter ("@Operator3", GKstudent.cobOperator3  ),
                new SqlParameter ("@Content1", GKstudent.txtContent1  ),
                new SqlParameter ("@Content2", GKstudent.txtContent2  ),
                new SqlParameter ("@Content3", GKstudent.txtContent3  ),
                new SqlParameter ("@Relation1", GKstudent.cobRelations1  ),
                new SqlParameter ("@Relation2", GKstudent.cobRelations2  )
            };
            dt = sqlhelper.ExecuteQuery(sql, paras, CommandType.StoredProcedure);

            return dt;
        }
</span></span>

存储过程的内容

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-family:KaiTi_GB2312;">Create</span> procedure [dbo].[GroupCheck]
(
@Field1 char(20),
@Field2 char(20),
@Field3 char(20),
@Operator1 char(20),
@Operator2 char(20),
@Operator3 char(20),
@Content1 char(20),
@Content2 char(20),
@Content3 char(20),
@Relation1 char(20),
@Relation2 char(20)
)
as
begin
declare @sql varchar(2000)
select @sql ='select * from Worklog where ' + @Field1+ @Operator1+ @Content1 if @Relation1!=''
select @sql =@sql + @Field2+ @Operator2+ @Content2 if @Relation2!=''
select @sql =@sql + @Field3+ @Operator3+ @Content3 
exec(@sql)
end</span>

    这样操作员的工作记录就轻轻松松的实现了,同理学生上机记录查询,学生基本信息维护,金额返还信息查询查询一样,只用把不一样的内容稍加修改就ok,再也不用像第一次机房时的复制粘贴了,这样减少了代码的冗余,也为我们节约了敲代码的负担,真正体会到了设计模式的强大力量。

小结

    做机房的时候一直害怕害怕,感觉组合查询很难很复杂,所以一直拖着拖着,不敢动手去做,其实真的当你鼓足勇气开始做,并一步一步前进,直到完成的时候,会发现其实并没有想象中的困难,只用去做一定可以实现,不要总是停在开始的路上,畏惧不敢向前,加油去做,尝试去当勇者。



你可能感兴趣的:(C#版的组合查询+模板方法)