开发应用-观察者模式之C#实现缓存数据更新
开发应用-观察者模式之C#实现缓存数据更新
我们在开发大型基于数据库管理应用系统时,会用到大量的缓存数据,这样能提高软件系统的性能,使用缓存数据带来便利的同时,也会因为用户更新了原始数据,如增、删、改导致缓存数据不同步更新,变成了旧数据、脏数据!
如何能同步更新缓存数据呢?
我想大家都会遇到这个问题,特整理了一套方案仅供参考:
观察者模式(Observer Facade Pattern)


定义一组观察者,他们时刻监视用户对原始数据的操作。
观察者模式接口

具体数据的业务逻辑层

/// <summary>
/// 观察者模式接口
/// </summary>
public interface IObserver
{
//仅一个方法,通知(Notify)观察者接收到消息
void Notify();
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 货币资料业务逻辑
///
///
/// </summary>
public class CurrencyData
{
private DataTable _Data; //货币数据,缓存数据
private IList _Observers = new ArrayList();//货币资料的观察者(1...n)
private string _xml = Application.StartupPath @"\data\currency.xml";
public DataTable DataSource { get { return _Data; } }
public void CreateTable()
{
_Data = new DataTable("Currency");
if (File.Exists(_xml))
_Data.ReadXml(_xml);
else
{
_Data.Columns.Add("CurrencyCode", typeof(string));
}
}
public void AddCurrency(string code)
{
_Data.LoadDataRow(new object[] { code }, true);
_Data.AcceptChanges(); //更新缓存的数据
_Data.WriteXml(_xml, XmlWriteMode.WriteSchema);//保存到文件
this.NotifyObservers();//通知所有观察者刷新数据
}
public void DeleteCurrency(string code)
{
DataRow[] rows = _Data.Select("CurrencyCode='" code "'");
if (rows.Length > 0) rows[0].Delete();
_Data.AcceptChanges();//更新缓存的数据
_Data.WriteXml(_xml, XmlWriteMode.WriteSchema); //保存到文件
this.NotifyObservers();//通知所有观察者刷新数据
}
/// <summary>
/// 通知所有观察者
/// </summary>
private void NotifyObservers()
{
foreach (IObserver o in _Observers) o.Notify();
}
/// <summary>
/// 登记观察者
/// </summary>
/// <param name="observers">观察者列表(1..n)</param>
public void RegisterObserver(IList observers)
{
foreach (IObserver o in observers)
{
//if (o is ObserverCurrency) _Observers.Add(o);
_Observers.Add(o);
}
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网

观察者模式(Observer Facade Pattern)


定义一组观察者,他们时刻监视用户对原始数据的操作。
观察者模式接口

具体数据的业务逻辑层

/// <summary>
/// 观察者模式接口
/// </summary>
public interface IObserver
{
//仅一个方法,通知(Notify)观察者接收到消息
void Notify();
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 支持数据字典观察者的窗体,比如PO,PN等业务窗体
/// Lookup功能视为数据字典观察者
/// </summary>
public interface IObserverSupportable
{
//获取观察者列表, 通常业务窗体内会对应多个数据字典表
IList GetObservers();
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// 支持数据字典观察者的窗体,比如PO,PN等业务窗体
/// Lookup功能视为数据字典观察者
/// </summary>
public interface IObserverSupportable
{
//获取观察者列表, 通常业务窗体内会对应多个数据字典表
IList GetObservers();
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 数据字典窗体
/// </summary>
public interface IObserverDataDictForm
{
//
//注册观察者,当字典数据改变时通知所有观察者同步更新数据.
//
//一个数据字典可能会关联多个业务窗体.比如货币字典会在采购窗体和窗体内使用.
//因此,当字典数据改变时要通知采购窗体和窗体刷新数据.
//
void RegisterObserver(IList observers);
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// 数据字典窗体
/// </summary>
public interface IObserverDataDictForm
{
//
//注册观察者,当字典数据改变时通知所有观察者同步更新数据.
//
//一个数据字典可能会关联多个业务窗体.比如货币字典会在采购窗体和窗体内使用.
//因此,当字典数据改变时要通知采购窗体和窗体刷新数据.
//
void RegisterObserver(IList observers);
}
// 来源:www.CSFramework.com, C/S结构框架学习网
public class ObserverAdd : IObserver
{
private ListBox _Monitor;
public ObserverAdd(ListBox monitor)
{
_Monitor = monitor;
}
public void Notify()
{
_Monitor.Items.Add("观察到新增记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
{
private ListBox _Monitor;
public ObserverAdd(ListBox monitor)
{
_Monitor = monitor;
}
public void Notify()
{
_Monitor.Items.Add("观察到新增记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
public class ObserverDelete : IObserver
{
private ListBox _Monitor;
public ObserverDelete(ListBox monitor)
{
_Monitor = monitor;
}
public void Notify()
{
_Monitor.Items.Add("观察到删除记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
{
private ListBox _Monitor;
public ObserverDelete(ListBox monitor)
{
_Monitor = monitor;
}
public void Notify()
{
_Monitor.Items.Add("观察到删除记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 同步刷新货币数据字典的观察者
/// </summary>
public class ObserverCurrency : IObserver
{
private ComboBox _CurrencyData;
private ListBox _log;
public ObserverCurrency(ComboBox comboBox, ListBox log)
{
_CurrencyData = comboBox;
_log = log;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\currency.xml");
_CurrencyData.DataSource = null;
_CurrencyData.DisplayMember = "CurrencyCode";
_CurrencyData.ValueMember = "CurrencyCode";
_CurrencyData.DataSource = dt;//绑定数据源
_log.Items.Add("客户窗体刚才通知了观察者!");
_log.Items.Add("刷新数据完成! 共下载了 " dt.Rows.Count.ToString() " 条记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// 同步刷新货币数据字典的观察者
/// </summary>
public class ObserverCurrency : IObserver
{
private ComboBox _CurrencyData;
private ListBox _log;
public ObserverCurrency(ComboBox comboBox, ListBox log)
{
_CurrencyData = comboBox;
_log = log;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\currency.xml");
_CurrencyData.DataSource = null;
_CurrencyData.DisplayMember = "CurrencyCode";
_CurrencyData.ValueMember = "CurrencyCode";
_CurrencyData.DataSource = dt;//绑定数据源
_log.Items.Add("客户窗体刚才通知了观察者!");
_log.Items.Add("刷新数据完成! 共下载了 " dt.Rows.Count.ToString() " 条记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 同步刷新客户数据字典的观察者
/// </summary>
public class ObserverCustomer : IObserver
{
private ComboBox _CustomerData;
private ListBox _log;
public ObserverCustomer(ComboBox comboBox, ListBox log)
{
_CustomerData = comboBox;
_log = log;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\customer.xml");
_CustomerData.DataSource = null;
_CustomerData.DisplayMember = "CustomerCode";
_CustomerData.ValueMember = "CustomerCode";
_CustomerData.DataSource = dt;
_log.Items.Add("客户窗体刚才通知了观察者!");
_log.Items.Add("刷新数据完成! 共下载了 " dt.Rows.Count.ToString() " 条记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// 同步刷新客户数据字典的观察者
/// </summary>
public class ObserverCustomer : IObserver
{
private ComboBox _CustomerData;
private ListBox _log;
public ObserverCustomer(ComboBox comboBox, ListBox log)
{
_CustomerData = comboBox;
_log = log;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\customer.xml");
_CustomerData.DataSource = null;
_CustomerData.DisplayMember = "CustomerCode";
_CustomerData.ValueMember = "CustomerCode";
_CustomerData.DataSource = dt;
_log.Items.Add("客户窗体刚才通知了观察者!");
_log.Items.Add("刷新数据完成! 共下载了 " dt.Rows.Count.ToString() " 条记录!");
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
public class ObserverUnit : IObserver
{
private ComboBox _UnitComboBox;
public ObserverUnit(ComboBox box)
{
_UnitComboBox = box;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\unit.xml");
_UnitComboBox.DataSource = null;
_UnitComboBox.DisplayMember = "UnitCode";
_UnitComboBox.ValueMember = "UnitCode";
_UnitComboBox.DataSource = dt;//绑定数据源
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
{
private ComboBox _UnitComboBox;
public ObserverUnit(ComboBox box)
{
_UnitComboBox = box;
}
public void Notify()
{
//模模拟从SQL Server取数据
DataTable dt = new DataTable();
dt.ReadXml(Application.StartupPath @"\data\unit.xml");
_UnitComboBox.DataSource = null;
_UnitComboBox.DisplayMember = "UnitCode";
_UnitComboBox.ValueMember = "UnitCode";
_UnitComboBox.DataSource = dt;//绑定数据源
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网
/// <summary>
/// 货币资料业务逻辑
///
///
/// </summary>
public class CurrencyData
{
private DataTable _Data; //货币数据,缓存数据
private IList _Observers = new ArrayList();//货币资料的观察者(1...n)
private string _xml = Application.StartupPath @"\data\currency.xml";
public DataTable DataSource { get { return _Data; } }
public void CreateTable()
{
_Data = new DataTable("Currency");
if (File.Exists(_xml))
_Data.ReadXml(_xml);
else
{
_Data.Columns.Add("CurrencyCode", typeof(string));
}
}
public void AddCurrency(string code)
{
_Data.LoadDataRow(new object[] { code }, true);
_Data.AcceptChanges(); //更新缓存的数据
_Data.WriteXml(_xml, XmlWriteMode.WriteSchema);//保存到文件
this.NotifyObservers();//通知所有观察者刷新数据
}
public void DeleteCurrency(string code)
{
DataRow[] rows = _Data.Select("CurrencyCode='" code "'");
if (rows.Length > 0) rows[0].Delete();
_Data.AcceptChanges();//更新缓存的数据
_Data.WriteXml(_xml, XmlWriteMode.WriteSchema); //保存到文件
this.NotifyObservers();//通知所有观察者刷新数据
}
/// <summary>
/// 通知所有观察者
/// </summary>
private void NotifyObservers()
{
foreach (IObserver o in _Observers) o.Notify();
}
/// <summary>
/// 登记观察者
/// </summary>
/// <param name="observers">观察者列表(1..n)</param>
public void RegisterObserver(IList observers)
{
foreach (IObserver o in observers)
{
//if (o is ObserverCurrency) _Observers.Add(o);
_Observers.Add(o);
}
}
}
// 来源:www.CSFramework.com, C/S结构框架学习网

参考文档:
开发应用-RepositoryItemLookUpEdit显示名称
开发应用 - 策略模式(Strategy Pattern) 常用设计模式
开发应用-命令模式(C#实现POS收银功能)
开发应用-职责链模式(Chain Of Resposibility Pattern)
使用观察者模式实时更新程序打开多个界面绑定组件的数据源
C/S架构软件开发平台 | 旗舰版V6 主页|C/S开发框架
软件优势 | TMS | 物流运输管理系统|C/S开发框架
软件简介 | TMS | 物流运输管理系统|C/S开发框架
C/S架构轻量级快速开发框架简介| WinFramework V2.1(2021 release)|C/S开发框架
C/S架构快速开发平台-旗舰版V5.1 (2021最新版)-C/S开发框架
.NET,VS,C#三者关系-C/S开发框架
C#/.NET Core简单认识-C/S开发框架
物流运输管理系统TMS成功案例-CSFramework快速开发框架(Winform+C/S+SQLServer)
CSFramework.WebApi后端服务器框架:客户端调用WebApi接口方式(签名+Token令牌)
LookupEdit.EditValueChanged事件内给其它文本框赋值无效或变回原来的值
LookupEdit关联更新其它文本输入框的值(自动带出参考数据并赋值)
开发应用-RepositoryItemLookUpEdit显示名称
开发应用 - 策略模式(Strategy Pattern) 常用设计模式
开发应用-命令模式(C#实现POS收银功能)
开发应用-职责链模式(Chain Of Resposibility Pattern)
使用观察者模式实时更新程序打开多个界面绑定组件的数据源
C/S架构软件开发平台 | 旗舰版V6 主页|C/S开发框架
软件优势 | TMS | 物流运输管理系统|C/S开发框架
软件简介 | TMS | 物流运输管理系统|C/S开发框架
C/S架构轻量级快速开发框架简介| WinFramework V2.1(2021 release)|C/S开发框架
C/S架构快速开发平台-旗舰版V5.1 (2021最新版)-C/S开发框架
.NET,VS,C#三者关系-C/S开发框架
C#/.NET Core简单认识-C/S开发框架
物流运输管理系统TMS成功案例-CSFramework快速开发框架(Winform+C/S+SQLServer)
CSFramework.WebApi后端服务器框架:客户端调用WebApi接口方式(签名+Token令牌)
LookupEdit.EditValueChanged事件内给其它文本框赋值无效或变回原来的值
LookupEdit关联更新其它文本输入框的值(自动带出参考数据并赋值)
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 |
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 |
在线客服
