昨晚看了看chr的职位,现在的公司都不爱出钱了,哎,职位也少。不过没关系,慢慢来,骑驴找马。
昨天折腾一天项目遗留的bug,潜伏期还真长,不知道当年哪个愣头青写的。测试部老大没在,暂时先不用发版,反正不是什么严重的bug。暂时先让客服去打点吧。
看别人写的代码总是那么的费尽(当然这里包括优雅的代码),如果再不带上注释,头大。不过好在编译器比较牛,大不了跑起来断点了,省得一行一行看。
说到这里想起来两个面试经历,一个是我的,一个是我朋友的。先说我朋友的吧,当时他去某公司面试,面官问他:asp和asp.net的最大区别是什么? 我朋友当然是尽浑身解数讲解,但最后还是被否定。面官给了答案:asp.net比asp方便调试!当时我听了那个寒阿,现在想想还真有道理,要是asp的项目,调个垃圾代码的bug得累死人。
第二个经历是我去某国内知名大型电子商务网站面试经历(为了这公司的脸面就不公布名称了了),其间一道笔试题,我答得比较满意,但后来面官告诉我这写的不对。当时我特虚心问应该怎么做,面官就说应该如此如此。我一听不对,和题上某些细节冲突,于是我就提出了这个冲突。最后,人老先生看了看,把题改了!!然后告诉我,你看,这样就对了。我这个瀑布寒,一脑袋黑线。
书归正传,继续说框架。
今儿说的是配置管理。之前说了这些个项目都没有统一的配置管理。没有统一的公共配置源,没有专员维护,以前都是各写各的,最后出现很多同值(同功能),不同命名甚至差异很大。造成在项目维护,重构中困难重重。于是弄了个这个项目,来统一管理配置。其实这个项目不足以单独胜任,还要配合一个配置发布的项目。
另外这个项目也不是完整的功能,可以说是一个模板,继承并实现相关的子类逻辑就好了。winform或者单园池这样的可以直接重载,多园多负载的还是需要回收内存。
先放上代码以供下载。
/Files/rachehunter/ConfigManager.rar
另外可以如下实现:
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Text;
using ConfigManager;
using ConfigManager.ConfigVisitor;
using RHTools;
using RHTools.RHUiti;
namespace ZSConfig
{
public sealed class ConfigService : BaseConfig
{
private static object lockHelper = new object();
private ConfigService()
{
}
#region Property
#region private
private string configServiceUrl = String.Empty;
/// <summary>
/// ConfigServiceUrl
/// </summary>
private string ConfigServiceUrl
{
get { return configServiceUrl; }
}
#endregion
#region public
private string mySqlDBConfigFilePath = String.Empty;
/// <summary>
/// MySqlDBConfigFilePath
/// </summary>
public string MySqlDBConfigFilePath
{
get { return mySqlDBConfigFilePath; }
}
private string interfaceConfigFilePath = String.Empty;
/// <summary>
/// InterfaceConfigFilePath
/// </summary>
public string InterfaceConfigFilePath
{
get { return interfaceConfigFilePath; }
}
private string securityConfigFilePath = String.Empty;
/// <summary>
/// SecurityConfigFilePath
/// </summary>
public string SecurityConfigFilePath
{
get { return securityConfigFilePath; }
}
private string onlineCacheFilePath = String.Empty;
/// <summary>
/// OnlineCacheFilePath
/// </summary>
public string OnlineCacheFilePath
{
get { return onlineCacheFilePath; }
}
#endregion
#endregion
public override void Reload()
{
this.configServiceUrl = base.Read("ConfigServiceUrl");
IConfigVistior vistiorConfigService = null;
if (!RHString.StrIsEmtpy(this.configServiceUrl))
{
vistiorConfigService = IConfigVistiorFactory.GetInstance(VistiorType.Xml);
vistiorConfigService.SetConfigFilePath(this.configServiceUrl);
}
this.mySqlDBConfigFilePath = base.Read(vistiorConfigService, "MySqlDBConfig");
this.interfaceConfigFilePath = base.Read(vistiorConfigService, "InterfaceConfig");
this.securityConfigFilePath = base.Read(vistiorConfigService, "SecurityConfig");
this.onlineCacheFilePath = base.Read(vistiorConfigService, "OnlineCacheFilePath");
}
#region Instance
private volatile static ConfigService instance = null;
/// <summary>
///
/// </summary>
public static ConfigService Instance
{
get
{
if (instance == null)
{
lock (lockHelper)
{
if (instance == null)
{
instance = new ConfigService();
}
}
}
if (instance == null)
{
RHDebug.ThrowExcetpion(new ArgumentNullException("ConfigService ConfigManage: unknown error"), true, "ConfigService ConfigManage 未知错误");
}
return instance;
}
}
#endregion
}
}
另外值得说的是这个项目不应局限于配置,也可以做一些其他的缓存。设计思路为单件缓存,监听重载。
附上部分文档:
命名空间:ConfigManager.ConfigVisitor
1. IConfigVistior配置源访问器接口。
void SetConfigFilePath(string path)设定读取的配置文件路径
string ReadConfig(string key) 读取配置节点数据
2. IConfigVistiorFactory配置源访问器工厂。根据枚举值生成配置源访问器实例。
3. VistiorType配置源访问器枚举。
4. WebConfigVistior Web.Config访问器。读取AppSettings配置。
5. XmlConfigVistior Xml配置访问器。
需要Xml配置按以下格式书写。可以读取远程Xml文档
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<test1>value1</test1>
</Config>
在使用时需要先调用SetConfigFilePath设置路径,然后再进行读取。
命名空间:ConfigManager
6. BaseConfig 配置管理类的基类。
protected BaseConfig() 载入配置信息,并将本身添加至配置管理列表类实例
protected IConfigVistior WebConfig WebConfig访问器,默认提供WebConfig配置读取,当读取配置失败时也会调用此访问器在WebConfig中查找
protected virtual string GetConfigFilePathFromBaseConfig(string configFile) 从基础配置中获取配置文件的位置。提供从WebConfig中读取Xml配置文件路径节点。
protected string Read(string key) WebConfig配置访问器读取配置
protected string Read(IConfigVistior vistior, string key) 按传入的配置访问器读取配置
public abstract void Reload() 要求实现读取配置的方法
7. Reloader配置管理类实例的监听者类。
private List<BaseConfig> configManagers配置管理类实例的列表。
public void Reload() 重新载入全部配置。调用每个配置管理类的Reload方法。
public void Add2List(BaseConfig bcm) 将配置管理类实例添加至列表
public static Reloader Loader 配置管理类监听者的唯一实例
其中不论是配置访问器还是管理类都可以自行扩展,当然要有专人来维护。我是不喜欢用反射的,因为反射太消耗效率了,所以我的工厂都不提供反射实例化。如果需要维护则由我负责。虽然会延长工期,增加部分维护量,但我觉得在大项目中这点工作还是值得牺牲的。