/// <summary> /// The 'Flyweight' interface ///享元模式 Flyweight Pattern /// geovindu,Geovin Du edit /// 车辆 /// </summary> interface IVehicle { /* * Client will supply the color. * It is extrinsic state. */ /// <summary> /// /// </summary> /// <param name="color">输入颜色</param> void AboutMe(string color); } /// <summary> /// A 'ConcreteFlyweight' class called Car /// 汽车 /// </summary> class Car : IVehicle { /* * It is intrinsic state and * it is independent of flyweight context. * this can be shared.So, our factory method will supply * this value inside the flyweight object. */ /// <summary> /// 描述 /// </summary> private string description; /* * Flyweight factory will supply this * inside the flyweight object. */ /// <summary> /// /// </summary> /// <param name="description">输入描述</param> public Car(string description) { this.description = description; } //Client will supply the color /// <summary> /// /// </summary> /// <param name="color">输入颜色</param> public void AboutMe(string color) { Console.WriteLine($"{description} 为 {color} ."); } } /// <summary> /// A 'ConcreteFlyweight' class called Bus /// 公交车 /// </summary> class Bus : IVehicle { /* * It is intrinsic state and * it is independent of flyweight context. * this can be shared.So, our factory method will supply * this value inside the flyweight object. */ /// <summary> /// 描述 /// </summary> private string description; /// <summary> /// /// </summary> /// <param name="description">输入描述</param> public Bus(string description) { this.description = description; } //Client will supply the color /// <summary> /// /// </summary> /// <param name="color">输入颜色</param> public void AboutMe(string color) { Console.WriteLine($"{description} 为 {color} ."); } } /// <summary> /// A 'ConcreteFlyweight' class called FutureVehicle /// 未来车辆 /// </summary> class FutureVehicle : IVehicle { /* * It is intrinsic state and * it is independent of flyweight context. * this can be shared.So, our factory method will supply * this value inside the flyweight object. */ /// <summary> /// 描述 /// </summary> private string description; /// <summary> /// /// </summary> /// <param name="description">输入描述</param> public FutureVehicle(string description) { this.description = description; } //Client cannot choose color for FutureVehicle //since it's unshared flyweight,ignoring client's input /// <summary> /// /// </summary> /// <param name="color">输入颜色</param> public void AboutMe(string color) { Console.WriteLine($"{description} 为 {color} ."); } } /// <summary> /// The factory class for flyweights implemented as singleton. /// 车辆工厂类 /// </summary> class VehicleFactory { /// <summary> /// /// </summary> private static readonly VehicleFactory Instance = new VehicleFactory(); /// <summary> /// /// </summary> private Dictionary<string, IVehicle> vehicles = new Dictionary<string, IVehicle>(); /// <summary> /// /// </summary> private VehicleFactory() { vehicles.Add("小汽车", new Car("一辆小汽车制造")); vehicles.Add("公交车", new Bus("一辆公交车制造")); vehicles.Add("概念车", new FutureVehicle("概念车 T2050 制造")); } /// <summary> /// /// </summary> public static VehicleFactory GetInstance { get { return Instance; } } /* * To count different type of vehicle * in a given moment. */ /// <summary> /// 数量 /// </summary> public int TotalObjectsCreated { get { return vehicles.Count; } } /// <summary> /// /// </summary> /// <param name="vehicleType"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public IVehicle GetVehicleFromVehicleFactory(string vehicleType) { IVehicle vehicleCategory = null; if (vehicles.ContainsKey(vehicleType)) { vehicleCategory = vehicles[vehicleType]; return vehicleCategory; } else { throw new Exception("Currently, the vehicle factory can have cars and buses only."); } } }
/// <summary> ///享元模式 Flyweight Pattern /// geovindu,Geovin Du edit /// </summary> public class FormattedText { /// <summary> /// /// </summary> private readonly string plainText; /// <summary> /// /// </summary> /// <param name="plainText"></param> public FormattedText(string plainText) { this.plainText = plainText; capitalize = new bool[plainText.Length]; } /// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> public void Capitalize(int start, int end) { for (int i = start; i <= end; ++i) capitalize[i] = true; } /// <summary> /// /// </summary> private readonly bool[] capitalize; /// <summary> /// 大写 /// </summary> /// <returns></returns> public override string ToString() { var sb = new StringBuilder(); for (var i = 0; i < plainText.Length; i++) { var c = plainText[i]; sb.Append(capitalize[i] ? char.ToUpper(c) : c); } return sb.ToString(); } } /// <summary> /// /// </summary> public class BetterFormattedText { private readonly string plainText; private readonly List<TextRange> formatting = new List<TextRange>(); /// <summary> /// /// </summary> /// <param name="plainText"></param> public BetterFormattedText(string plainText) { this.plainText = plainText; } /// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> public TextRange GetRange(int start, int end) { var range = new TextRange { Start = start, End = end }; formatting.Add(range); return range; } /// <summary> /// 大写 /// </summary> /// <returns></returns> public override string ToString() { var sb = new StringBuilder(); for (var i = 0; i < plainText.Length; i++) { var c = plainText[i]; foreach (var range in formatting) if (range.Covers(i) && range.Capitalize) c = char.ToUpperInvariant(c); sb.Append(c); } return sb.ToString(); } /// <summary> /// /// </summary> public class TextRange { public int Start, End; public bool Capitalize, Bold, Italic; public bool Covers(int position) { return position >= Start && position <= End; } } }
调用:
//享元模式 Flyweight Pattern Console.WriteLine("***享元模式 Flyweight Pattern Demo.***\n"); //VehicleFactory vehiclefactory = new VehicleFactory(); VehicleFactory vehiclefactory = VehicleFactory.GetInstance; IVehicle vehicle; /* * Now we are trying to get the 3 cars. * Note that:we need not create additional cars if * we have already created one of this category */ for (int i = 0; i < 3; i++) { vehicle = vehiclefactory.GetVehicleFromVehicleFactory("小汽车"); vehicle.AboutMe("绿色"); } int numOfDistinctRobots = vehiclefactory.TotalObjectsCreated; Console.WriteLine($"\n Now, total numbers of distinct vehicle object(s) is = {numOfDistinctRobots}\n"); /*Here we are trying to get the 5 more buses. * Note that: we need not create * additional buses if we have * already created one of this category */ for (int i = 0; i < 5; i++) { vehicle = vehiclefactory.GetVehicleFromVehicleFactory("公交车"); vehicle.AboutMe("红色"); } numOfDistinctRobots = vehiclefactory.TotalObjectsCreated; Console.WriteLine($"\n Now, total numbers of distinct vehicle object(s) is = {numOfDistinctRobots}\n"); /*Here we are trying to get the 2 future vehicles. * Note that: we need not create * additional future vehicle if we have * already created one of this category */ for (int i = 0; i < 2; i++) { vehicle = vehiclefactory.GetVehicleFromVehicleFactory("概念车"); vehicle.AboutMe("白色"); } numOfDistinctRobots = vehiclefactory.TotalObjectsCreated; Console.WriteLine($"\n Now, total numbers of distinct vehicle object(s) is = {numOfDistinctRobots}\n"); #region test for in-built flyweight pattern Console.WriteLine("**Testing String interning in .NET now.**"); string firstString = "A simple string"; string secondString = new StringBuilder().Append("A").Append(" simple").Append(" string").ToString(); string thirdString = String.Intern(secondString); Console.WriteLine((Object)secondString == (Object)firstString); // Different references. Console.WriteLine((Object)thirdString == (Object)firstString); // The same reference. #endregion //大写 var ft = new FormattedText("This is a geovindu new world"); ft.Capitalize(10, 17); Console.WriteLine(ft); //大写 var bft = new BetterFormattedText("This is a lukfook new world"); bft.GetRange(10, 16).Capitalize = true; Console.WriteLine(bft); Console.ReadKey();
输出:
***享元模式 Flyweight Pattern Demo.*** 一辆小汽车制造 为 绿色 . 一辆小汽车制造 为 绿色 . 一辆小汽车制造 为 绿色 . Now, total numbers of distinct vehicle object(s) is = 3 一辆公交车制造 为 红色 . 一辆公交车制造 为 红色 . 一辆公交车制造 为 红色 . 一辆公交车制造 为 红色 . 一辆公交车制造 为 红色 . Now, total numbers of distinct vehicle object(s) is = 3 概念车 T2050 制造 为 白色 . 概念车 T2050 制造 为 白色 . Now, total numbers of distinct vehicle object(s) is = 3 **Testing String interning in .NET now.** False True This is a GEOVINDU new world This is a LUKFOOK new world