享元模式结构:
![]()
1 using Newtonsoft.Json;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace DesignPattern.StructuralPattern
9 {
10 #region 享元模式
11 //定义:不在每个对象中保存所有数据,而是通过共享对象所共有的相同状态,减少内存压力
12 //优点:降低频繁创建对象造成的内存压力
13 //缺点:系统变得更复杂
14 //使用场景:对象
15 //实现方式:
16 /*
17 *
18 1.将需要改写为享元的类成员变量拆分为两个部分:
19 内在状态: 包含不变的,可在许多对象中重复使用的数据的成员变量。
20 外在状态: 包含每个对象各自不同的状态数据的成员变量。
21 2.保留类中表示内在状态的成员变量,这些变量仅可在构造函数中获得初始数值,初始化后不能修改。
22 3.外在状态所需数据由客户端传入,调用享元类中方法,作为参数传入。
23 4.创建工厂类来管理享元缓存池,负责在新建享元时检查已有的享元。
24 客户端通过享元的内在状态作为参数key,传递给工厂来请求目标享元。
25 5.客户端必须存储和计算外在状态的数值, 因为只有这样才能调用享元对象的方法。
26 也可将外在状态和引用享元的成员变量移动到单独的情景类中。
27
28 */
29
30 #endregion
31
32
33 public abstract class FlyweightPattern
34 {
35 protected Car _sharedData = new Car();
36 public FlyweightPattern(Car car)
37 {
38 _sharedData.Company = car.Company;
39 _sharedData.Model = car.Model;
40 _sharedData.Color = car.Color;
41 }
42
43 public abstract void PassUniqueState(Car uniqueData);
44 }
45
46 public class Flyweight : FlyweightPattern
47 {
48 public Flyweight(Car car) : base(car)
49 {
50
51 }
52
53 //use uniqueData to do something
54 public override void PassUniqueState(Car uniqueData)
55 {
56 string shared = JsonConvert.SerializeObject(this._sharedData);
57 string unique = JsonConvert.SerializeObject(uniqueData);
58
59 Console.WriteLine($"shared data = {shared},unique data = {uniqueData.Owner} + {uniqueData.Number}");
60 }
61 }
62
63 public class Car
64 {
65 //外部状态 作为参数传入
66 public string Owner { get; set; }
67
68 public string Number { get; set; }
69
70
71 //共享数据作为内部状态
72 public string Company { get; set; }
73
74 public string Model { get; set; }
75
76 public string Color { get; set; }
77 }
78
79
80 public class FlyweightFactory
81 {
82 private Dictionary<string, FlyweightPattern> cache = new Dictionary<string, FlyweightPattern>();
83 public FlyweightFactory(params Car[] sharedData)
84 {
85 foreach (var item in sharedData)
86 {
87 GetFlyweight(item);
88 }
89 }
90
91 public FlyweightPattern GetFlyweight(Car car)
92 {
93 string key = GetKey(car);
94 if (cache.ContainsKey(key))
95 {
96 return cache[key];
97 }
98 else
99 {
100 FlyweightPattern flyweight = new Flyweight(car);
101 cache.Add(key, flyweight);
102 return flyweight;
103 }
104 }
105
106 private string GetKey(Car car)
107 {
108 return string.Join("_", car.Company, car.Model, car.Color);
109 }
110
111 public void ListFlyweight()
112 {
113 Console.WriteLine($"total count: {cache.Count}");
114 foreach (var item in cache)
115 {
116 Console.WriteLine($"{item.Key}");
117 }
118 }
119 }
120
121 public class FlyweightClient
122 {
123 public static void Test()
124 {
125 // 添加需要缓存的数据
126
127 var factory = new FlyweightFactory(
128 new Car { Company = "Chevrolet", Model = "Camaro2018", Color = "pink" },
129 new Car { Company = "Mercedes Benz", Model = "C300", Color = "black" },
130 new Car { Company = "Mercedes Benz", Model = "C500", Color = "red" },
131 new Car { Company = "BMW", Model = "M5", Color = "red" },
132 new Car { Company = "BMW", Model = "X6", Color = "white" }
133 );
134
135 Car car = new Car
136 {
137 Company = "Chevrolet",
138 Model = "Camaro2018",
139 Color = "pink",
140 Owner = "Howie",
141 Number = "H666"
142 };
143
144 addCarToPoliceDatabase(factory, car);
145
146 car.Owner = "Spike";
147 car.Number = "S888";
148
149 //实现复用
150 addCarToPoliceDatabase(factory, car);
151 }
152
153 public static void addCarToPoliceDatabase(FlyweightFactory factory, Car car)
154 {
155 Console.WriteLine("\nClient: Adding a car to database.");
156
157 var flyweight = factory.GetFlyweight(car);
158
159 flyweight.PassUniqueState(car);
160 factory.ListFlyweight();
161 }
162 }
163 }