一次让代码更适应变化的经历

一般情况下,我写的程序在界面装载时,读取配置文件中的各个项目,中间使用或修改后,在界面退出时,保存一下配置文件。

在还不是面对对象年代,基本上都会把读配置文件中的一个项目、写配置文件中的一个项目都写成一个子程序,这样调用方便。当需要多增加新的一个项目时,只要在界面装载、界面退出时,各增加一行。当时感觉已经是不错的处理方案了。

Program.cs 中“读写INI的API”代码

        // 声明INI文件的写操作函数 WritePrivateProfileString()
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern int WritePrivateProfileString(string section, string key, string val, string filePath);

        // 声明INI文件的读操作函数 GetPrivateProfileString()
        [System.Runtime.InteropServices.DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);

        public static bool bWriteINIValue(string sSection, string sKeyName, string sText, string sINIFileName)
        {
            int lRet = WritePrivateProfileString(sSection, sKeyName, sText, sINIFileName);
            if (lRet == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static string sGetINIValue(string sSection, string sKeyName, string sDefault, string sINIFileName)
        {
            int lRet;
            System.Text.StringBuilder sTemp = new StringBuilder(255);
            lRet = GetPrivateProfileString(sSection, sKeyName, sDefault, sTemp, 255, sINIFileName);
            if (lRet == 0)
            {
                return string.Empty;
            }
            else
            {
                return sTemp.ToString();
            }
        }
View Code

Form1.cs 代码(界面还放一个按钮)

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication12
{
    public partial class Form1 : Form
    {
        string sXM1 = string.Empty;
        string sXM2 = string.Empty;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sXM1 = sGetINIValue("Normal", "XM1", "", Application.StartupPath + "\Para.ini");
            sXM2 = sGetINIValue("Normal", "XM2", "", Application.StartupPath + "\Para.ini");
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            bWriteINIValue("Normal", "XM1", sXM1, Application.StartupPath + "\Para.ini");
            bWriteINIValue("Normal", "XM2", sXM2, Application.StartupPath + "\Para.ini");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string sTemp = sXM1;
            MessageBox.Show(sTemp);
            sXM2 = DateTime.Now.ToString("hh:mm:ss");
        }
    }
}

它存在的问题是:程序员要知道界面装载时读取(一般这个会记得),同时也要知道界面退出时要保存(甚至有时并不全在界面退出时保存,可能有个保存按钮的点击事件中处理)。否则程序员经常写的代码就是忘记保存。

面对对象的编程中,能否实现在程序的一个地方设置后,程序员就可以不必管其它地方的代码?

我想出来的解决方案如下:
1、建立一个项目类 —— ClsXM,它有 名称,默认值,当前值(为代码简单,使用变量而不是使用属性)
2、建立项目类集合 —— ClsXMJH,实现AddRange、GetAllValue、SaveAllValue、索引器(我刻意不实现 IList、IDictionary接口,因为这次的需求比较少)

ClsXM.cs代码

using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication12
{
    class ClsXM
    {
        public string Name = string.Empty;
        public string Default = string.Empty;
        public string Value = string.Empty;

        public ClsXM(string sName)
        {
            this.Name = sName;
        }

        public void GetValue()
        {
            Value = Program.sGetINIValue("Normal", Name, Default, Application.StartupPath + "\Para.ini");
        }

        public void SaveValue()
        {
            Program.bWriteINIValue("Normal", Name, Value, Application.StartupPath + "\Para.ini");
        }
    }
}

ClsXMJH.cs 代码

using System.Collections.Generic;

namespace WindowsFormsApplication12
{
    class ClsXMJH
    {
        List<ClsXM> oXM = new List<ClsXM>();

        public void AddRange(params ClsXM[] oItems)
        {
            foreach (ClsXM oTemp in oItems)
            {
                oXM.Add(oTemp);
            }
        }

        public void GetAllValue()
        {
            foreach (ClsXM oTempXM in oXM)
            {
                oTempXM.GetValue();
            }
        }

        public void SaveAllValue()
        {
            foreach (ClsXM oTempXM in oXM)
            {
                oTempXM.SaveValue();
            }
        }

        public ClsXM this[string sName]
        {
            get
            {
                ClsXM oRet = null;
                foreach (ClsXM oTempXM in oXM)
                {
                    if (oTempXM.Name == sName)
                    {
                        oRet = oTempXM;
                        break;
                    }
                }

                return oRet;
            }
        }
    }
}

Form1.cs 改后的代码

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication12
{
    public partial class Form1 : Form
    {
        ClsXMJH oXMJH = new ClsXMJH();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            oXMJH.AddRange(new ClsXM("XM1"), new ClsXM("XM2"));

            oXMJH.GetAllValue();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            oXMJH.SaveAllValue();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string sTemp = oXMJH["XM1"].Value;
            MessageBox.Show(sTemp);
            oXMJH["XM2"].Value = DateTime.Now.ToString("hh:mm:ss");
        }
    }
}

现在想问的是这是否是正确的解决方案?是否还存在更好的解决方案?是否有与此相关的设计模式,它叫什么名称?

原文地址:https://www.cnblogs.com/yzx99/p/3375314.html