设计模式(C#) 享元模式(Flyweight Pattern)【转】

  享元模式是避免大量相同或相似对象的出现而出现的设计模式,一般出现的对象不可能是一样的对象,它们可能很相似,只是一部分表现或者说是状态不一样,这样,我们就可以把他们相同的部分抽象出来,封装起来,称之为内状态,然后不一样的地方,称之为外状态,通过一定的方法加进对象中去,这样就达到对象重用的效果,不用再创建那么多对象。

#region 享元模式

#region 需求说明
//概述
//面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
//意图
//运用共享技术有效地支持大量细粒度的对象。[GOF 《设计模式》]
#endregion

#region 案例说明
//考虑这样一个字处理软件,它需要处理的对象可能有单个的字符,由字符组成的段落以及整篇文档,根据面向对象的设计思想和Composite模式,不管是字符还是段落,文档都应该作为单个的对象去看待,这里只考虑单个的字符,不考虑段落及文档等对象。
#endregion

#region 用法说明
//效果及实现要点
//1.面向对象很好的解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
//2.Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
//3.享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。另外它将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
//适用性
//当以下所有的条件都满足时,可以考虑使用享元模式:
//1、   一个系统有大量的对象。
//2、   这些对象耗费大量的内存。
//3、   这些对象的状态中的大部分都可以外部化。
//4、   这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中剔除时,每一个组都可以仅用一个对象代替。
//5、   软件系统不依赖于这些对象的身份,换言之,这些对象可以是不可分辨的。
//满足以上的这些条件的系统可以使用享元对象。最后,使用享元模式需要维护一个记录了系统已有的所有享元的表,而这需要耗费资源。因此,应当在有足够多的享元实例可供共享时才值得使用享元模式。
//总结
//Flyweight模式解决的是由于大量的细粒度对象所造成的内存开销的问题,它在实际的开发中并不常用,但是作为底层的提升性能的一种手段却很有效。
#endregion

示例

有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支持这些对象。


MessageModel

using System;
using System.Collections.Generic;
using System.Text;

namespace Pattern.Flyweight
{
  /**//// <summary>
  /// Message实体类
  /// </summary>
  public class MessageModel
  {
    /**//// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="msg">Message内容</param>
    /// <param name="pt">Message发布时间</param>
    public MessageModel(string msg, DateTime pt)
    {
      this._message = msg;
      this._publishTime = pt;
    }

    private string _message;
    /**//// <summary>
    /// Message内容
    /// </summary>
    public string Message
    {
      get { return _message; }
      set { _message = value; }
    }

    private DateTime _publishTime;
    /**//// <summary>
    /// Message发布时间
    /// </summary>
    public DateTime PublishTime
    {
      get { return _publishTime; }
      set { _publishTime = value; }
    }
  }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace Pattern.Flyweight
{
  /**//// <summary>
  /// 操作Message抽象类(Flyweight)
  /// </summary>
  public abstract class AbstractMessage
  {
    /**//// <summary>
    /// 获取Message
    /// </summary>
    /// <returns></returns>
    public abstract List<MessageModel> Get();

    /**//// <summary>
    /// 插入Message
    /// </summary>
    /// <param name="mm">Message实体对象</param>
    /// <returns></returns>
    public abstract bool Insert(MessageModel mm);
  }
}

SqlMessage

using System;
using System.Collections.Generic;
using System.Text;

namespace Pattern.Flyweight
{
  /**//// <summary>
  /// Sql方式操作Message(ConcreteFlyweight)
  /// </summary>
  public class SqlMessage : AbstractMessage
  {
    /**//// <summary>
    /// 获取Message
    /// </summary>
    /// <returns></returns>
    public override List<MessageModel> Get()
    {
      List<MessageModel> l = new List<MessageModel>();
      l.Add(new MessageModel("SQL方式获取Message", DateTime.Now));

      return l;
    }

    /**//// <summary>
    /// 插入Message
    /// </summary>
    /// <param name="mm">Message实体对象</param>
    /// <returns></returns>
    public override bool Insert(MessageModel mm)
    {
      // 代码略
      return true;
    }
  }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace Pattern.Flyweight
{
  /**//// <summary>
  /// Xml方式操作Message(ConcreteFlyweight)
  /// </summary>
  public class XmlMessage : AbstractMessage
  {
    /**//// <summary>
    /// 获取Message
    /// </summary>
    /// <returns></returns>
    public override List<MessageModel> Get()
    {
      List<MessageModel> l = new List<MessageModel>();
      l.Add(new MessageModel("XML方式获取Message", DateTime.Now));

      return l;
    }

    /**//// <summary>
    /// 插入Message
    /// </summary>
    /// <param name="mm">Message实体对象</param>
    /// <returns></returns>
    public override bool Insert(MessageModel mm)
    {
      // 代码略
      return true;
    }
  }
}

MessageFactory

using System;
using System.Collections.Generic;
using System.Text;

namespace Pattern.Flyweight
{
  /**//// <summary>
  /// Message工厂(FlyweightFactory)
  /// </summary>
  public class MessageFactory
  {
    private Dictionary<string, AbstractMessage> _messageObjects = new Dictionary<string, AbstractMessage>();

    /**//// <summary>
    /// 获取Message对象
    /// </summary>
    /// <param name="key">key</param>
    /// <returns></returns>
    public AbstractMessage GetMessageObject(string key)
    {
      AbstractMessage messageObject = null;

      if (_messageObjects.ContainsKey(key))
      {
        messageObject = _messageObjects[key];
      }
      else
      {
        switch (key)
        {
          case "xml": messageObject = new SqlMessage(); break;
          case "sql": messageObject = new XmlMessage(); break;
        }

        _messageObjects.Add(key, messageObject);
      }

      return messageObject;
    }
  }
}

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Pattern.Flyweight;

public partial class Flyweight : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    string[] ary = new string[] { "xml", "sql" };

    MessageFactory messageFactory = new MessageFactory();

    foreach (string key in ary)
    {
      AbstractMessage messageObject = messageFactory.GetMessageObject(key);

      Response.Write(messageObject.Insert(new MessageModel("插入", DateTime.Now)));
      Response.Write("<br />");
      Response.Write(messageObject.Get()[0].Message + " " + messageObject.Get()[0].PublishTime.ToString());
      Response.Write("<br />");
    }
  }
}

运行结果

True

SQL方式获取Message 2007-5-17 22:20:38

True

XML方式获取Message 2007-5-17 22:20:38

参考

http://www.dofactory.com/Patterns/PatternFlyweight.aspx

原文地址:https://www.cnblogs.com/myssh/p/1781147.html