1. 程式人生 > >Design Pattern - Flyweight(C#)

Design Pattern - Flyweight(C#)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

Definition

Use sharing to support large numbers of fine-grained objects efficiently.

Participants

    The classes and/or objects participating in this pattern are:

  • Flyweight (Character)
    • Declares an interface through which flyweights can receive and act on extrinsic state.
  • ConcreteFlyweight (CharacterA, CharacterB, ..., CharacterZ)
    • Implements the Flyweight interface and adds storage for intrinsic state, if any. A ConcreteFlyweight object must be sharable. Any state it stores must be intrinsic, that is, it must be independent of the ConcreteFlyweight object's context.
  • UnsharedConcreteFlyweight (not used)
    • Not all Flyweight subclasses need to be shared. The Flyweight interface enables sharing, but it doesn't enforce it. It is common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the flyweight object structure (as the Row and Column classes have).
  • FlyweightFactory (CharacterFactory)
    • Creates and manages flyweight objects
    • Ensures that flyweight are shared properly. When a client requests a flyweight, the FlyweightFactory objects assets an existing instance or creates one, if none exists.
  • Client (FlyweightApp)
    • Maintains a reference to flyweight(s).
    • Computes or stores the extrinsic state of flyweight(s).

Sample code in C#


This structural code demonstrates the Flyweight pattern in which a relatively small number of objects is shared many times by different clients.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Flyweight Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    using System.Collections;    /// <summary>    /// Startup class for Structural Flyweight Design Pattern.    /// </summary>    internal static class Program    {        #region Methods        /// <summary>        /// Entry point into console application.        /// </summary>        private static void Main()        {            // Arbitrary extrinsic state            int extrinsicstate = 22;            var factory = new FlyweightFactory();            // Work with different flyweight instances            Flyweight fx = factory.GetFlyweight("X");            fx.Operation(--extrinsicstate);            Flyweight fy = factory.GetFlyweight("Y");            fy.Operation(--extrinsicstate);            Flyweight fz = factory.GetFlyweight("Z");            fz.Operation(--extrinsicstate);            var fu = new UnsharedConcreteFlyweight();            fu.Operation(--extrinsicstate);        }        #endregion    }    /// <summary>    /// The 'FlyweightFactory' class    /// </summary>    internal class FlyweightFactory    {        #region Fields        /// <summary>        /// The flyweights.        /// </summary>        private Hashtable flyweights = new Hashtable();        #endregion        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="FlyweightFactory"/> class.        /// </summary>        public FlyweightFactory()        {            this.flyweights.Add("X", new ConcreteFlyweight());            this.flyweights.Add("Y", new ConcreteFlyweight());            this.flyweights.Add("Z", new ConcreteFlyweight());        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The get flyweight.        /// </summary>        /// <param name="key">        /// The key.        /// </param>        /// <returns>        /// The <see cref="Flyweight"/>.        /// </returns>        public Flyweight GetFlyweight(string key)        {            return (Flyweight)this.flyweights[key];        }        #endregion    }    /// <summary>    /// The 'Flyweight' abstract class    /// </summary>    internal abstract class Flyweight    {        #region Public Methods and Operators        /// <summary>        /// The operation.        /// </summary>        /// <param name="extrinsicstate">        /// The extrinsic state.        /// </param>        public abstract void Operation(int extrinsicstate);        #endregion    }    /// <summary>    /// The 'ConcreteFlyweight' class    /// </summary>    internal class ConcreteFlyweight : Flyweight    {        #region Public Methods and Operators        /// <summary>        /// The operation.        /// </summary>        /// <param name="extrinsicstate">        /// The extrinsic state.        /// </param>        public override void Operation(int extrinsicstate)        {            Console.WriteLine("ConcreteFlyweight: " + extrinsicstate);        }        #endregion    }    /// <summary>    /// The 'UnsharedConcreteFlyweight' class    /// </summary>    internal class UnsharedConcreteFlyweight : Flyweight    {        #region Public Methods and Operators        /// <summary>        /// The operation.        /// </summary>        /// <param name="extrinsicstate">        /// The extrinsic state.        /// </param>        public override void Operation(int extrinsicstate)        {            Console.WriteLine("UnsharedConcreteFlyweight: " + extrinsicstate);        }        #endregion    }}// Output:/*ConcreteFlyweight: 21ConcreteFlyweight: 20ConcreteFlyweight: 19UnsharedConcreteFlyweight: 18*/

This real-world code demonstrates the Flyweight pattern in which a relatively small number of Character objects is shared many times by a document that has potentially many characters.

// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Real-World Flyweight Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{    using System;    using System.Collections.Generic;    /// <summary>    /// Startup class for Real-World Flyweight Design Pattern.    /// </summary>    internal static class Program    {        #region Methods        /// <summary>        /// Entry point into console application.        /// </summary>        private static void Main()        {            // Build a document with text            const string Document = "AAZZBBZB";            char[] chars = Document.ToCharArray();            var factory = new CharacterFactory();            // extrinsic state            int pointSize = 10;            // For each character use a flyweight object            foreach (char c in chars)            {                pointSize++;                Character character = factory.GetCharacter(c);                character.Display(pointSize);            }        }        #endregion    }    /// <summary>    /// The 'FlyweightFactory' class    /// </summary>    internal class CharacterFactory    {        #region Fields        /// <summary>        /// The characters.        /// </summary>        private Dictionary<char, Character> characters = new Dictionary<char, Character>();        #endregion        #region Public Methods and Operators        /// <summary>        /// The get character.        /// </summary>        /// <param name="key">        /// The key.        /// </param>        /// <returns>        /// The <see cref="Character"/>.        /// </returns>        public Character GetCharacter(char key)        {            // Uses "lazy initialization"            Character character = null;            if (this.characters.ContainsKey(key))            {                character = this.characters[key];            }            else            {                switch (key)                {                    case 'A':                        character = new CharacterA();                        break;                    case 'B':                        character = new CharacterB();                        break;                    // ...                    case 'Z':                        character = new CharacterZ();                        break;                }                this.characters.Add(key, character);            }            return character;        }        #endregion    }    /// <summary>    /// The 'Flyweight' abstract class    /// </summary>    internal abstract class Character    {        #region Fields        /// <summary>        /// The ascent.        /// </summary>        protected int Ascent;        /// <summary>        /// The descent.        /// </summary>        protected int Descent;        /// <summary>        /// The height.        /// </summary>        protected int Height;        /// <summary>        /// The point size.        /// </summary>        protected int PointSize;        /// <summary>        /// The symbol.        /// </summary>        protected char Symbol;        /// <summary>        /// The width.        /// </summary>        protected int Width;        #endregion        #region Public Methods and Operators        /// <summary>        /// The display.        /// </summary>        /// <param name="pointSize">        /// The point size.        /// </param>        public abstract void Display(int pointSize);        #endregion    }    /// <summary>    /// A 'ConcreteFlyweight' class    /// </summary>    internal class CharacterA : Character    {        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="CharacterA"/> class.        /// </summary>        public CharacterA()        {            this.Symbol = 'A';            this.Height = 100;            this.Width = 120;            this.Ascent = 70;            this.Descent = 0;        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The display.        /// </summary>        /// <param name="pointSize">        /// The point size.        /// </param>        public override void Display(int pointSize)        {            this.PointSize = pointSize;            Console.WriteLine(this.Symbol + " (point size " + this.PointSize + ")");        }        #endregion    }    /// <summary>    /// A 'ConcreteFlyweight' class    /// </summary>    internal class CharacterB : Character    {        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="CharacterB"/> class.        /// </summary>        public CharacterB()        {            this.Symbol = 'B';            this.Height = 100;            this.Width = 140;            this.Ascent = 72;            this.Descent = 0;        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The display.        /// </summary>        /// <param name="pointSize">        /// The point size.        /// </param>        public override void Display(int pointSize)        {            this.PointSize = pointSize;            Console.WriteLine(this.Symbol + " (point size " + this.PointSize + ")");        }        #endregion    }    // ... C, D, E, etc.    /// <summary>    /// A 'ConcreteFlyweight' class    /// </summary>    internal class CharacterZ : Character    {        // Constructor        #region Constructors and Destructors        /// <summary>        /// Initializes a new instance of the <see cref="CharacterZ"/> class.        /// </summary>        public CharacterZ()        {            this.Symbol = 'Z';            this.Height = 100;            this.Width = 100;            this.Ascent = 68;            this.Descent = 0;        }        #endregion        #region Public Methods and Operators        /// <summary>        /// The display.        /// </summary>        /// <param name="pointSize">        /// The point size.        /// </param>        public override void Display(int pointSize)        {            this.PointSize = pointSize;            Console.WriteLine(this.Symbol + " (point size " + this.PointSize + ")");        }        #endregion    }}// Output:/*A (point size 11)A (point size 12)Z (point size 13)Z (point size 14)B (point size 15)B (point size 16)Z (point size 17)B (point size 18)*/
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述