zoukankan      html  css  js  c++  java
  • 设计模式(C#)——10享元模式

    推荐阅读:

    前言

          在软件开发中,当我们需要对某些对象重复创建,且最终只需要得到单一结果。如果使用一般思维,那我们将浪费很多内存空间,为此,我们引入享元模式。

    介绍

          所谓享元模式即共享对象,该模式利用先前创建的已有对象,通过某种规则去判断当前所需对象是否可以利用原有对象做相应修改后得到想要的效果,如果可以,则只需要修改该对象的某些属性以达到要求,否则,则创建新对象。享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。

    享元模式的要素:

    1、抽象享元(Flyweight):它是所有具体享元类的抽象基类,为其子类规定出需要实现的公共接口;
    2、具体享元(Concrete Flyweight):具体享元类实现了抽象享元类所规定的接口;
    3、享元工厂(FlyweightFactoiy):享元工厂类负责创建和管理享元对象。

    下面举个例子:

    例如:在游戏中敌人的生成,生成的敌人往往是不同的,生成的位置不同,颜色不通等。下面,我们假设生成的是同一种敌人,但是它的y坐标不固定。

    命名空间享元模式中包含AbEnemy充当抽象享元,Enemy类充当具体享元,FactoyEnemy工厂类充当享元工厂。本案例通过使用享元模式来实现敌人的生成。

    下面使用代码实现享元模式:
    1.创建抽像享元AbEnemy

    public abstract class AbEnemy
    {
    	public string color;
    	public int x;
    	public int y;
    	public AbEnemy()
    	{
    	    color = "红";
    	    x = 100;
    	}
    	 
    	public override string ToString()
    	{
    	    return string.Format("生成{0}颜色的敌人,位置在X为{1},Y为{2}", color, x, y);
    	}
    }
    

    2.创建具体享元

    public class Enemy:AbEnemy
    {
    	public Enemy(int posY)
    	{
    	    y = posY;
    	}
    }
    

    3.创建一个工厂,生成基于给定信息的实体类的对象

     
    public class FactoyEnemy
    {
    	private Dictionary<int, Enemy> EnemyList;
    	public FactoyEnemy()
    	{
    	    EnemyList = new Dictionary<int, Enemy>();
    	    EnemyList.Add(1, new Enemy(100));
    	    EnemyList.Add(2, new Enemy(200));
    	}
    	public Enemy GetEnemy(int num)
    	{
    	    return EnemyList[num] as Enemy;
    	}
    }
    

    4.使用该工厂,通过传递颜色信息来获取实体类的对象

    class Program
    {
    	static void Main(string[] args)
    	{
    	    FactoyEnemy factoryEnemy = new FactoyEnemy();
    	    Enemy enemy = factoryEnemy.GetEnemy(1);
    	    Console.WriteLine(enemy.ToString());
    	    enemy = factoryEnemy.GetEnemy(2);
    	    Console.WriteLine(enemy.ToString());
    	    Console.ReadKey();
    	}
    }
    

    整合后的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace 享元模式
    {
        public abstract class AbEnemy
    	{
    	    public string color;
    	    public int x;
    	    public int y;
    	    public AbEnemy()
    	    {
    	        color = "红";
    	        x = 100;
    	    }
    	 
    	    public override string ToString()
    	    {
    	        return string.Format("生成{0}颜色的敌人,位置在X为{1},Y为{2}", color, x, y);
    	    }
    	}
    	
    	public class Enemy:AbEnemy
    	{
    	    public Enemy(int posY)
    	    {
    	        y = posY;
    	    }
    	}
    		
    	public class FactoyEnemy
    	{
    	    private Dictionary<int, Enemy> EnemyList;
    	    public FactoyEnemy()
    	    {
    	        EnemyList = new Dictionary<int, Enemy>();
    	        EnemyList.Add(1, new Enemy(100));
    	        EnemyList.Add(2, new Enemy(200));
    	    }
    	    public Enemy GetEnemy(int num)
    	    {
    	        return EnemyList[num] as Enemy;
    	    }
    	}
    
    	class Program
    	{
    	    static void Main(string[] args)
    	    {
    	        FactoyEnemy factoryEnemy = new FactoyEnemy();
    	        Enemy enemy = factoryEnemy.GetEnemy(1);
    	        Console.WriteLine(enemy.ToString());
    	        enemy = factoryEnemy.GetEnemy(2);
    	        Console.WriteLine(enemy.ToString());
    	        Console.ReadKey();
    	    }
    	}
    }
    

    优缺点

    优点:
          大大减少对象的创建,降低系统的内存,使效率提高。

    缺点:
          提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。

    总结

    使用场景:
    1、一个系统中有大量的对象;
    2、这些对象耗费大量的内存;
    3、这些对象中的状态大部分都可以被外部化;
    4、这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替;
    5、软件系统不依赖这些对象的身份。

  • 相关阅读:
    Go语言趣学指南lesson3
    简单的>this
    多媒体查询
    解析对象原型链
    笑对人生,坐看云起云落
    HTML5
    javascript函数及作用域的小结
    不得不知call()和apply()
    浅谈弹性盒子布局
    编译原理实验(算符优先文法)
  • 原文地址:https://www.cnblogs.com/shirln/p/10245266.html
Copyright © 2011-2022 走看看