设计模式---享元模式

享元模式:解决对象的复用问题,提供第三方的管理,不破坏类的封装
      自行实例化对象,不像单例时强制保证
池化资源管理:
  享元工厂也可以初始化多个对象---其他地方需要使用对象可以找工厂拿(修改个状态)--用完之后在放回来(状态修改回来)
  避免重复的创建和销毁资源(特别是对于非托管资源,像:数据库连接,线程)

享元模式:

1.实现一:

public class FlyweightFactory
{
private static Dictionary<WordType, BaseWorld> FlyweightFactoryDictionary = new Dictionary<WordType, BaseWorld>();

/// <summary>
/// 1.如果是5个线程同时调用,字典为空,所以会同时构造5次E
/// 2.最后只只打印一个ELEVEN,因为其他线程都挂掉了,因为在字典中添加相同的值的时候,挂掉了
/// 3. 2个L是小概率事件,前两个线程是同时添加E,所以没有失败,所以L有两个,但是到L的时候又冲突了
/// 4.子线程的异常时看不到的,除非waitall
/// </summary>
/// <param name="wordType"></param>
/// <returns></returns>
public static BaseWorld CreateWord(WordType wordType)
{
if (!FlyweightFactoryDictionary.ContainsKey(wordType))
{
BaseWorld word = null;
switch (wordType)
{
case WordType.E:
word = new E();
break;
case WordType.L:
word = new L();
break;
case WordType.V:
word = new V();
break;
case WordType.N:
word = new N();
break;
default:
throw new Exception();
}
FlyweightFactoryDictionary.Add(wordType, word);
}

return FlyweightFactoryDictionary[wordType];
}
}

public enum WordType
{
E,
L,
V,
N
}

 

测试代码:

for (int i = 0; i < 5; i++)
{
Task.Run(() =>
{
BaseWorld e = FlyweightFactory.CreateWord(WordType.E);
BaseWorld l = FlyweightFactory.CreateWord(WordType.L);
BaseWorld V = FlyweightFactory.CreateWord(WordType.V);
BaseWorld n = FlyweightFactory.CreateWord(WordType.N);
Console.WriteLine("{0}{1}{2}{3}{4}{5}", e.Get(), l.Get(), e.Get(), V.Get(), e.Get(), n.Get());
});
}

测试结果:

 

 

2.实现方式二:

public class FlyweightFactory
{
private static Dictionary<WordType, BaseWorld> FlyweightFactoryDictionary = new Dictionary<WordType, BaseWorld>();

/// <summary>
/// 不想看到多线程的时候生成多个E,加锁
/// </summary>
private readonly static object FlyweightFactoryLock = new object();

/// <summary>
/// 1.如果是5个线程同时调用,字典为空,所以会同时构造5次E
/// 2.最后只只打印一个ELEVEN,因为其他线程都挂掉了,因为在字典中添加相同的值的时候,挂掉了
/// 3. 2个L是小概率事件,前两个线程是同时添加E,所以没有失败,所以L有两个,但是到L的时候又冲突了
/// 4.子线程的异常时看不到的,除非waitall
/// </summary>
/// <param name="wordType"></param>
/// <returns></returns>
public static BaseWorld CreateWord(WordType wordType)
{
if (!FlyweightFactoryDictionary.ContainsKey(wordType))
//是为了性能优化,避免对象已经被初始化后,再次请求还需要等待锁
{
lock (FlyweightFactoryLock)//相当于Monitor.Enter, 保证方法体只有一个线程可以进入
{
if (!FlyweightFactoryDictionary.ContainsKey(wordType))
{
BaseWorld word = null;
switch (wordType)
{
case WordType.E:
word = new E();
break;
case WordType.L:
word = new L();
break;
case WordType.V:
word = new V();
break;
case WordType.N:
word = new N();
break;
default:
throw new Exception();
}
FlyweightFactoryDictionary.Add(wordType, word);
}
}
}

return FlyweightFactoryDictionary[wordType];
}
}

public enum WordType
{
E,
L,
V,
N
}

 

 

测试结果:

 

posted @ 2020-02-15 21:18  wbxs  阅读(87)  评论(0编辑  收藏  举报