-
Flyweight Pattern]
享元模式: 主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
String常量池、数据库连接池、缓冲池等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。 -
实现方式
用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象。用 HashMap、Hash Table存储这些对象。 -
享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
-
享元对象能做到共享的关键是区分内部状态和外部状态。
其中内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,因此内部状态可以共享;
外部状态是随环境改变而改变的、不可以共享的状态。 -
代码示例
/*
* Flyweight Pattern :享元模式。
* String常量池、数据库连接池、缓冲池等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。
*
*/
using System;
using System.Collections;
namespace Pattern01
{
class Program
{
static void Main(string[] args)
{
int extrinsicstate = 22;//外部状态参数
Flyweight fx = FlyweightFactory.GetFlyweight("x");
fx.Operation(--extrinsicstate);
Flyweight fy = FlyweightFactory.GetFlyweight("Y");
fy.Operation(--extrinsicstate);
Flyweight fz = FlyweightFactory.GetFlyweight("z");
fz.Operation(--extrinsicstate);
//申请已有对象,直接从池中返回
Flyweight fx1 = FlyweightFactory.GetFlyweight("x");
fx1.Operation(--extrinsicstate);
//不可共享对象,直接new
UnsharedConcreteFlyweight fu = new UnsharedConcreteFlyweight();
fu.Operation(--extrinsicstate);
Console.ReadKey();
}
}
/// <summary>
/// FlyweightFactory
/// 享元工厂类用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中。
/// </summary>
class FlyweightFactory
{
private static Hashtable pool = new Hashtable();
public static Flyweight GetFlyweight(string key)
{
Flyweight flyweight = null;
if (pool.ContainsKey(key))
{
flyweight = (Flyweight)pool[key];
Console.WriteLine("already exist, 从池中直接取出:" + key);
}
else
{
flyweight = new ConCreteFlyweight();
pool.Add(key, flyweight);
Console.WriteLine($"创建:{key} 并将其加入pool中");
}
return flyweight;
}
}
/// <summary>
/// the flyWeight abstract class:
/// 抽象享元类声明一个接口,通过它可以接受并作用于外部状态;
/// </summary>
abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
/// <summary>
/// ConCreteFlyweight
/// 具体享元类实现了抽象享元接口,其实例称为享元对象;
/// </summary>
class ConCreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("ConcreteFlyweight:" + extrinsicstate);
}
}
/// <summary>
/// UnsharedConcreteFlyweight
/// 非共享具体享元是不能被共享的抽象享元类的子类;
/// </summary>
class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("UnsharedConcreteFlyweight:" + extrinsicstate);
}
}
}
- *** 代码示例***
创建一个 Shape 接口和实体类 Circle实现Shape接口。定义工厂类 ShapeFactory。
ShapeFactory 检查它的 dictionary中的 circle 对象,如果找到 Circle 对象,则返回该对象,否则将创建一个存储在 dictionary中以备后续使用的新对象,并把该对象返回到客户端。
/*
* Flyweight Pattern
*/
using System;
using System.Collections;
using System.Collections.Generic;
namespace Pattern02
{
class Program
{
static void Main(string[] args)
{
Shape red = ShapeFactory.GetCircle("red");
red.Draw();
Shape green = ShapeFactory.GetCircle("green");
green.Draw();
Shape blue = ShapeFactory.GetCircle("blue");
blue.Draw();
///创建相同对象时,直接从池中返回对象。
Shape red2 = ShapeFactory.GetCircle("red");
red2.Draw();
Console.ReadLine();
}
}
/// <summary>
/// flyweight
/// </summary>
interface Shape
{
void Draw();
}
/// <summary>
/// concrete Flyweight
/// </summary>
class Circle : Shape
{
private string color;
public Circle(string color)
{
this.color = color;
}
public void Draw()
{
Console.WriteLine($"draw a {color} circle");
}
}
/// <summary>
/// flyWeight factory
/// </summary>
class ShapeFactory
{
private static Dictionary<string, Shape> pool = new Dictionary<string, Shape>();
public static Shape GetCircle(string color)
{
Circle circle = null;
if (pool.ContainsKey(color))
{
circle = (Circle)pool[color];
Console.WriteLine($"already exist ,从池中取 {color} circle");
}
else
{
circle = new Circle(color);
pool.Add(color, circle);
Console.WriteLine($"创建 {color} circle, 并加入到pool中");
}
return circle;
}
}
}