目录
一、享元模式
运用共享技术有效地支持大量细粒度的对象。
享元模式要注重内部状态和外部状态。
内部状态是不随外界环境改变的存储在享元对象内部的。内部状态可以共享。
外部状态随外界改变,不可以共享。享元对象外部状态要在客户端保存,有需要时传入享元对象内部。内外独立。
使用条件:
1、一个系统要很多对象。
2、这些对象耗费大量内存
3、对象的大部分状态可以外部化。
4、这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替。
优点
1、大幅度降低内存中对象数量,节省了内存空间
缺点
1、使得系统更加复杂
2、为了使得对象可以共享,需要将一些状态外部化,这使得程序逻辑更加复杂。
其本质是分离和共享。享元模式中有两种状态,一种是内部,另一种是外部。在享元对象内部且 不会随着环境变化的部分叫做内部状态。
在编辑器中经常使用这个模式,在五子棋、围棋只有黑白两子的棋中也能应用这些模式。
二、享元模式角色
1、享元类接口,通过这个接口,可以接受并作用于外部状态。
2、享元工厂,创建并管理享元对象。
3、内部状态类,继承享元类,为内部状态增加存储空间。
4、外部状态类,不需要共享的享元子类。
三、代码实例一
网站共享代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightOne
{
abstract class Website
{
public abstract void Use();
}
}
第二个类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightOne
{
class WebsiteOne : Website
{
private string name;
public WebsiteOne(string name)
{
this.name = name;
}
public override void Use()
{
Console.WriteLine("网站分类是:" + name);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightOne
{
class WebsiteFactory
{
private Hashtable fly = new Hashtable();
//哈希表,类似于MAP
public Website GetWebsite(string key)
{
if(!fly.ContainsKey(key))
{
fly.Add(key, new WebsiteOne(key));
}
return (Website)fly[key];
}
public int CountNum()
{
return fly.Count;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FlyWeightOne
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
WebsiteFactory fac = new WebsiteFactory();
Website fa = fac.GetWebsite("a");
fa.Use();
Website fb = fac.GetWebsite("b");
fa.Use();
}
}
}
四、代码实例二
有内部状态和外部状态之分
用户类(网站类外部状态)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightTwo
{
class User
{
private string name;
public User(string name)
{
this.Name = name;
}
public string Name { get => name; set => name = value; }
}
}
享元类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightTwo
{
abstract class Website
{
public abstract void Use(User user);
}
}
内部状态类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightTwo
{
class WebsiteOne:Website
{
private string name;
public WebsiteOne(string name)
{
this.name = name;
}
public override void Use(User user)
{
Console.WriteLine("网站分类是:" + name+" 用户是:"+user.Name);
}
}
}
工厂
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlyWeightTwo
{
class WebsiteFacory
{
private Hashtable fly = new Hashtable();
//哈希表,类似于MAP
public Website GetWebsite(string key)
{
if (!fly.ContainsKey(key))
{
fly.Add(key, new WebsiteOne(key));
}
return (Website)fly[key];
}
public int CountNum()
{
return fly.Count;
}
}
}
测试
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FlyWeightTwo
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
WebsiteFacory fac = new WebsiteFacory();
Website fa = new WebsiteOne("a");
fa.Use(new User("小一"));
Website fb = new WebsiteOne("b");
fb.Use(new User("小二"));
}
}
}