在一个程序设计里,不同的功能窗口有着相似的功能实现方式,可采用设计模式---模板方法模式

    前段时间学习了一些设计模式,最近在做项目的过程中恰巧用到了其中的一个--模板方法模式。这个模式在程序设计过程中可是为小编省去了不少的代码量呢。具体是怎样应用的呢?接下来小编为您分享。
    前面博文中小编已经分享了模板方法模式的理论点,下面将分享如何把这些理论点应用到实际的项目开发过程中。
※功能需求
    在程序设计过程中,有两个以上的窗口是实现组合查询功能,且基本结构都包括字段名、操作符、要查询的内容,以及操作符之间的组合关系,查出结果后将其导出、且导出的文件类型为Excel表。
    在实现上面的功能时,考虑到这些窗口有类似的实现流程,所以就采用了一个设计模式----模板方法模式来实现功能需求。

1、首先建立一个模板,即父窗体。在一个程序设计里,不同的功能窗口有着相似的功能实现方式,可采用设计模式---模板方法模式_第1张图片
把不同窗体中具有的相同结构都放在父窗体中,且在父窗体的代码中编写它们公有的事件和方法,以及实现特定功能的模板方法----虚方法,涉及到的具体的实现功能的查询方法需要在具体实现功能的窗体中去写[类似于接口一样,只提供抽象的方法,具体实现方法在D层中来实现。这里采用虚方法,在子窗体中进行重写]。在这个模板里,小编写的方法和事件有以下这些:


    namespace UI
{
    public partial class frmGroupFindFather : Form
    {
        public frmGroupFindFather()
        {
            InitializeComponent();
        }
        
        //查询
        private void btnQuerry_Click(object sender, EventArgs e)
        {
            //判断在容器panel上的控件 属性值 enabled为true的控件里的内容不能为空
            foreach (Control c1 in panel2.Controls)
            {
                if ((c1 is ComboBox||c1 is TextBox)&&c1 .Enabled ==true)
                {
                    if (c1 .Text.Trim()=="")
                    {
                        MessageBox.Show("请将信息填写完整!", "提示");
                        return;
                    }
                }
            }
            GroupFindtemplateFacade FGroupFind = new GroupFindtemplateFacade();//实例化外观层
            GroupFindtemplate groupInfo = new GroupFindtemplate();//实例化实体层
            
            //为实体层赋值
            groupInfo.Dbtable = GetDbTableName();
            groupInfo.CboFiled1 =GetEndlishFromFiled( CboFiled1.Text.Trim()); //字段需要采用中英转换的方法
            groupInfo.CboFiled2 =GetEndlishFromFiled( CboFiled2.Text.Trim());
            groupInfo.CboField3 = CboFiled3.Text.Trim();
            groupInfo.CboMark1 = CboMark1.Text.Trim();
            groupInfo.CboMark2 = CboMark2.Text.Trim();
            groupInfo.CboMark3 = CboMark3.Text.Trim();
            groupInfo.Cbotent1 = txtCbotent1.Text.Trim();
            groupInfo.Cbotent2 = txtCbotent2.Text.Trim();
            groupInfo.Cbotent3 = txtCbotent3.Text.Trim();
            groupInfo.Relationship1 = GetEndlishFromFiled(cboConbination1.Text.Trim());
            groupInfo.Relationship2 = GetEndlishFromFiled(cboConbination2.Text.Trim());
            
            bool flag = false;
            flag = FGroupFind.GroupFindtemplate(groupInfo);
            if (flag==true)
            {
                MessageBox.Show("查找成功!");
                DataTable dt = new DataTable();
                dt = FGroupFind.GroupFindTable(groupInfo);
                dgv.DataSource = dt;
                dgv.AllowUserToAddRows = false;
            }
            else
            {
                MessageBox.Show("无法查询您输入的信息,请重新输入!");
            }
        }
        
        //清空
         private void btnClear_Click(object sender, EventArgs e)
        {
	    Clear();//调用封装好的清空方法
            DataTable Table = null;
            dgv.DataSource = Table;
            LoadControl();//控件初始化方法
        }
	    
	    //清空的方法
        private void Clear()
        {
            foreach (Control c1 in panel2.Controls)
            {
                if (c1 is ComboBox||c1 is TextBox )
                {
                    c1.Text = "";
                }
            }
            cboConbination1.Text = "";
            cboConbination2.Text = "";
        }

	   //控件初始化方法
       private void LoadControl()
        {
            CboFiled2.Enabled = false;
            CboFiled3.Enabled = false;
            CboMark2.Enabled = false;
            CboMark3.Enabled = false;
            txtCbotent2.Enabled = false;
            txtCbotent3.Enabled = false;
            cboConbination1.Enabled = false;
            cboConbination2.Enabled = false;
        }
        
        //窗体加载的方法
       private void frmGroupFindFather_Load(object sender, EventArgs e)
        {
            LoadControl();//调用控件初始化方法
        }
        
        //当第一行的文本填充完整后,第一个组合关系被激活
        private void txtCbotent1_TextChanged_1(object sender, EventArgs e)
        {
            if (CboFiled1.Text != "" && CboMark1.Text != "" && txtCbotent1.Text != "")
            {
                cboConbination1.Enabled = true;
            }
        }
        //当选择第一个组合关系时  出现第二行信息框
        private void cboConbination1_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (cboConbination1.Text != "")
            {
                CboFiled2.Enabled = true;
                CboMark2.Enabled = true;
                txtCbotent2.Enabled = true;
            }
        }
        //当第二行的文本填充完整后,第二个组合关系被激活
        private void txtCbotent2_TextChanged(object sender, EventArgs e)
        {
            if (CboFiled2.Text != "" && CboMark2.Text != "" && txtCbotent2.Text != "")
            {
                cboConbination2.Enabled = true;
            }
        }
        //当选择第二个组合关系时  出现第三行信息框
         private void cboConbination2_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            if (cboConbination2.Text != "")
            {
                CboFiled3.Enabled = true;
                CboMark3.Enabled = true;
                txtCbotent3.Enabled = true;
            }
        }
        //构造一个没有任何返回值的虚方法 来根据字段内容出现相应的下拉内容
        public virtual void addcontent(ComboBox file,ComboBox mark)
        {  
        }
        #region 以下三个方法是根据字段的内容添加符号内容
        public  void CboFiled1_SelectedIndexChanged(object sender, EventArgs e)
        {
            addcontent(CboFiled1, CboMark1);
        }
         public  void CboFiled2_SelectedIndexChanged(object sender, EventArgs e)
        {
            addcontent(CboFiled2, CboMark2);
        }
        public  void CboFiled3_SelectedIndexChanged(object sender, EventArgs e)
        {
            addcontent(CboFiled3, CboMark3);
        }
        #endregion
        
        //定义一个数据库中不同表的名字的虚方法 在子窗体中进行重写,需要查询哪个表 就返回该表的表名
        public virtual string GetDbTableName()
        {
            return "";
        }
        //转换中文字符为英文字符,在字窗体就进行重写
        public virtual string GetEndlishFromFiled(string cbo)
        {
            return "";
        }

:父窗体的其他层编码方式与一般窗体编码形式类似,区别较大的就是DAL层。在这里,小编使用了存储过程。
在一个程序设计里,不同的功能窗口有着相似的功能实现方式,可采用设计模式---模板方法模式_第2张图片
在一个程序设计里,不同的功能窗口有着相似的功能实现方式,可采用设计模式---模板方法模式_第3张图片
2、然后创建具体实现特定功能窗口,即子窗体。

在子窗体中对父窗体里的虚方法进行重写,满足不同子窗体实现不同的、具体的功能。下面以Line_Info表为例:

	//方法重写:根据字段 添加操作符
      public override void addcontent(ComboBox cbofiled, ComboBox cbomark)
        {
            switch (cbofiled.Text)
            {
                case "用户名":
                case "性别":
                case "状态":
                    cbomark.Text = "";
                    cbomark.Items.Clear();
                    cbomark.Items.Add("=");
                    cbomark.Items.Add("<>");
                    break;
                case "卡号":
                    cbomark.Text = "";
                    cbomark.Items.Clear();
                    cbomark.Items.Add("=");
                    cbomark.Items.Add("<>");
                    cbomark.Items.Add(">");
                    cbomark.Items.Add("<");
                    break;
            }
        }
        //方法重写:获取数据库中表的名字的方法
         public override string GetDbTableName()
        {
            return "Line_Info";
        }
        //方法重写:将中文转换成数据库中相应字段的方法
        public override string GetEndlishFromFiled(string cbo)
        {
            switch (cbo)
            {
                case "用户名":
                    return "UserID";               
                case "性别":
                    return "sex";
                case "状态":
                    return "status";
                case "卡号":
                    return "cardno";
                case "或":
                    return "OR";
                case "且":
                    return "AND";
                default:
                    return "";
             }
        }

:其余的事件和方法在父窗体中已有定义,在子窗体中无需再写了。

    看了上面的分享,是不是感觉模板方法模式能为我们程序设计节省不少代码呢。在程序设计过程中,恰当的运用设计模式能达到事半功倍的效果呢。

希望本文能对您有所帮助哦^.^

你可能感兴趣的:(❀❀❀牛刀小试)