(原创)无废话C#设计模式之十九:Observer

本文通过一个分页显示数据的Web页面案例,详细介绍了如何使用C#实现观察者模式,解决多个UI组件间的一对多依赖问题,提高代码的可维护性和扩展性。

无废话C#设计模式之十九:Observer

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

场景

这次不说游戏了,假设我们需要在一个Web页面上分页显示数据。首先需要一个分页控制器和一个显示数据的表格。开始,客户的需求很简单,需要两个向前翻页向后翻页的按钮作为控制器,还需要一个GridView来显示数据。你可能会这么做:

l 在页面上放两个按钮和一个GridView控件

l 点击了下一页按钮判断是否超出了页面索引,如果没有的话更新GridView中的数据,然后更新控件的当前页,如果翻页后是最后一页的话把下一页按钮设置为不可用。

l 点击了上一页按钮判断是否超出了页面索引,如果没有的话更新GridView中的数据,然后更新控件的当前页,如果翻页后是第一页的话把上一页按钮设置为不可用。

在这里,我们的翻页控件仅仅和GridView进行依赖,看似问题不大。没有想到,客户看了Demo后觉得这样的体验不好,希望在页面上呈现当前页和总共页。于是,我们又在页面上加了一个Label控件,在按钮的点击事件里面再去更新Label控件的值。客户挺满意的,随着软件中数据越来越多,总页数达到了几十页,客户觉得前后翻页太不合理的了,希望有一个显示页数列表的分页控制器,客户的这个请求彻底使我们晕了,代码被我们修改的非常混乱:

l 点击了列表分页控件的页数后更新自身状态、通知GridView加载数据、通知按钮分页控件更新自身状态、通知Label更新页数信息。

l 点击了按钮分页控件后更新自身状态、通知GridView加载数据、通知列表分页控件更新自身状态、通知Label更新页数信息。

如果今后页面上还需要针对分页功能有任何修改的话,真不知道怎么去改。由此引入观察者模式来解决这些问题。

示例代码

using System;

using System.Collections.Generic;

using System.Text;

namespace ObserverExample

{

class Program

{

static void Main(string[] args)

{

ButtonPager buttonPager = new ButtonPager();

ListPager listPager = new ListPager();

Control gridview = new GridView();

Control label = new Label();

buttonPager.changePageHandler += new Pager.ChangePageHandler(buttonPager.ChangePage);

buttonPager.changePageHandler += new Pager.ChangePageHandler(gridview.ChangePage);

buttonPager.changePageHandler += new Pager.ChangePageHandler(label.ChangePage);

buttonPager.changePageHandler += new Pager.ChangePageHandler(listPager.ChangePage);

listPager.changePageHandler += new Pager.ChangePageHandler(buttonPager.ChangePage);

listPager.changePageHandler += new Pager.ChangePageHandler(gridview.ChangePage);

listPager.changePageHandler += new Pager.ChangePageHandler(label.ChangePage);

listPager.changePageHandler += new Pager.ChangePageHandler(listPager.ChangePage);

buttonPager.NextPage();

Console.WriteLine();

buttonPager.NextPage();

Console.WriteLine();

buttonPager.NextPage();

Console.WriteLine();

buttonPager.PreviousPage();

Console.WriteLine();

buttonPager.PreviousPage();

Console.WriteLine();

listPager.SelectPage(2);

Console.WriteLine();

listPager.SelectPage(1);

Console.WriteLine();

listPager.SelectPage(0);

}

}

abstract class Pager

{

protected int pageIndex = 0;

public int PageIndex

{

get { return pageIndex; }

set { pageIndex = value; }

}

protected int pageCount = 3;

public int PageCount

{

get { return pageCount; }

}

public event ChangePageHandler changePageHandler;

public delegate void ChangePageHandler(Pager sender);

protected void ChangePage()

{

if (changePageHandler != null)

changePageHandler(this);

}

}

class ButtonPager : Pager, Control

{

public void NextPage()

{

if (pageIndex < pageCount - 1)

{

Console.WriteLine("Click NextPage Button...");

pageIndex++;

ChangePage();

}

}

public void PreviousPage()

{

if (pageIndex > 0)

{

Console.WriteLine("Click PreviousPage Button...");

pageIndex--;

ChangePage();

}

}

public void ChangePage(Pager sender)

{

base.pageIndex = sender.PageIndex;

if (pageIndex > 0 && pageIndex < pageCount - 1)

Console.WriteLine("<<Previous Next>>");

else if (pageIndex == 0)

Console.WriteLine("Next>>");

else

Console.WriteLine("<<Previous");

}

}

class ListPager : Pager, Control

{

public void SelectPage(int pageIndex)

{

if (pageIndex >= 0 && pageIndex < pageCount)

{

Console.WriteLine(string.Format("Click <{0}> Link...", pageIndex + 1));

base.pageIndex = pageIndex;

ChangePage();

}

}

public void ChangePage(Pager sender)

{

base.pageIndex = sender.PageIndex;

for (int i = 1; i <= pageCount; i++)

{

if (pageIndex + 1 == i)

Console.Write(string.Format(" <{0}> ", i));

else

Console.Write(string.Format(" {0} ", i));

}

Console.WriteLine();

}

}

interface Control

{

void ChangePage(Pager sender);

}

class GridView : Control

{

public void ChangePage(Pager sender)

{

Console.WriteLine(string.Format("GridView->Show data of page {0}", sender.PageIndex + 1));

}

}

class

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值