23种设计模式-12-享元模式

mac2025-10-03  1

/// <summary> /// 车:内部状态 /// </summary> public class Car { public Car(string color) { this.Color = color; Console.WriteLine("Car被实例化,color = " + color); } public string Color { get; set; } public void Drive(Driver driver) { Console.WriteLine("{0}在开{1}的车!", driver.Name, Color); } } /// <summary> /// 司机:外部状态 /// </summary> public class Driver { public Driver(string name) { this.Name = name; } public string Name { get; set; } } /// <summary> /// 享元工厂:类似于车库 /// </summary> public class FlyweightFactory { /// <summary> /// 这里真实场景需要考虑到现场安全问题 /// 解决办法:1.lock;2.线程安全数据类型:ConcurrentDictionary;3.原子操作 /// 这里的Dictionary,在java里面相当于map,java开发者可以这样理解 /// 我这里使用lock,因为lock在C#和java都有,方便大家理解 /// </summary> private Dictionary<string, Car> CarContainer = new Dictionary<string, Car>(); /// <summary> /// 我这里使用lock防止并发,因为lock在C#和java都有,方便大家理解 /// readonly关键字此时相当于java的final关键字 /// </summary> private static readonly object CarLocker = new object(); public FlyweightFactory() { //最开始家里有两辆车,一辆白色,一辆黑色 this.CarContainer.Add("白色", new Car("白色")); this.CarContainer.Add("黑色", new Car("黑色")); } /// <summary> /// 从车库取车操作 /// </summary> /// <returns></returns> public Car GetCar(string color) { Car car = null; CoreService.RunLock(CarLocker, () => { //判断车库里面有没有这个颜色的车 if (CarContainer.ContainsKey(color)) { Console.WriteLine("车库里有{0}的车,直接从车库取走", color); //有这个颜色的就直接取车 car = CarContainer[color]; } else { Console.WriteLine("车库里没有{0}的车,去买一辆放在车库,然后取走", color); //没有的话,就买一辆新的,放在车库 CarContainer.Add(color, new Car(color)); //然后取出去,下次就不用买了,可以直接取 car = CarContainer[color]; } }); return car; } } class Program { /// <summary> /// 享元模式: /// 如果我们需要大量相同的对象,如果一个个去new的话,会导致很浪费资源和性能,而享元就是为了解决这个问题的 /// 看到这里,大家脑海里肯定会想:哎,这不是原型模式吗?怎么享元模式跟原型模式一样了? /// /// 让我来解释一下吧: /// 原型模式:为了避免new,而采用克隆的方式来构造对象(注重构造),原型模式是一个创建型模式,所以注重的是创建 /// 享元模式:不仅仅是为了避免new,更多的还是为了重用一个对象(注重重用),它的一些属性我们是可以直接用的。 /// /// 此文中的例子:大头儿子一家 /// 假如大头儿子一家三口,家里有两辆车,一辆白色,一辆黑色,然后家里每次出行时需要开车 /// 不可能说每一次出行都要去新买一辆车吧(new),所以只需要买一个(new一次),之后要使用,直接去车库开就好了 /// 如果家里的车不够了,假如大头儿子长大了,想要买一辆蓝色的车,此时车库里没有,则需要重新去买一辆放在车库里 /// 以后大头儿子要开车的话就可以从车库里去开了 /// /// 享元模式又分为:1.内部状态;2.外部状态; /// 内部状态:在享元的内部不会因为环境的改变而改变,在上述例子中车就是内部状态,只要买了就在车库,不会改变 /// 外部状态:会随环境改变而改变,不可以享元的状态,在上述例子中大头儿子一家就是外部状态,车不会变,但是谁开车,这个是会变化的,这个无法享元 /// </summary> /// <param name="args"></param> static void Main(string[] args) { //不管取多少遍车,同一个颜色的车,永远只会实例化一次(买一次) FlyweightFactory carFactory = new FlyweightFactory(); Car car1 = carFactory.GetCar("白色"); Car car2 = carFactory.GetCar("黑色"); Car car3 = carFactory.GetCar("蓝色"); carFactory.GetCar("白色"); carFactory.GetCar("黑色"); carFactory.GetCar("蓝色"); //指定外部环境(谁去开车) car1.Drive(new Driver("围裙妈妈")); car2.Drive(new Driver("小头爸爸")); car3.Drive(new Driver("大头儿子")); Console.WriteLine("End"); Console.ReadKey(); } }

 

最新回复(0)