• 5原型模式


    原型模式

    The key idea is that an object can spawn other objects similar to itself.

    原型模式的关键思想,是让一个对象可以产生与它自己相似的其他对象。

    假设一个场景中,我们需要生成很多数量的各种种类的敌怪。

    例如,先生成多个三种敌怪:幽灵、恶魔、魔法师。

    它们有各自的属性,因此我们要生成对应三种敌怪的生成器类。由生成器类去生成多个敌怪。

    示例代码

    	public class Monster
        {
            public string name = "";
            public int attack = 0;
        }
        class Ghost : Monster
        {
            public Ghost(string n)
            {
                this.name = n;
                this.attack = 10;
                Console.WriteLine("Create a Ghost:" + this.name + " atk:" + this.attack);
            }
        }
        public class Spawner
        {
            public virtual Monster spawnMonster()
            {
                Console.WriteLine("new Monster");
                return new Monster();
            }
        }
        public class GhostSpawner : Spawner
        {
            private int amount;
            public override Monster spawnMonster()
            {
                return new Ghost("g" + amount++);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    测试

    			GhostSpawner gs = new GhostSpawner();
                Ghost? g0 = gs.spawnMonster() as Ghost;
                Ghost? g1 = gs.spawnMonster() as Ghost;
    
                DemonSpawner ds = new DemonSpawner();
                Demon? d0 = ds.spawnMonster() as Demon;
                Demon? d1 = ds.spawnMonster() as Demon;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这样的写法,代码结构臃肿,每一个敌怪,都要定义一个对应的生成器类。

    那么,有没有办法,用一个生成器类,生成多个敌怪生成器变量呢?

    答案就是原型。原型在 JavaScript 中应用广泛。

    这跟工厂模式可能有点类似,就是传递一个敌怪对象作为原型,然后由生成器调用这个敌怪类的复制方法,从敌怪原型对象中克隆出一个新对象。

    下面继续看示例

    	public class Monster
        {
            public string name = "";
            public int attack = 0;
            // 原型模式
            public virtual Monster clone()
            {
                return new Monster();
            }
        }
        class Ghost : Monster
        {
            public Ghost(string n)
            {
                this.name = n;
                this.attack = 10;
                Console.WriteLine("Create a Ghost:" + this.name + " atk:" + this.attack);
            }
            // 原型模式
            public override Monster clone()
            {
                Console.WriteLine("Clone Ghost" + this.name + " atk:" + this.attack);
                return new Ghost(this.name);
            }
        }
        // 原型模式
        public class SpawnerPrototype
        {
            private Monster prototype;
            public SpawnerPrototype(Monster prototype)
            {
                this.prototype = prototype;
            }
            public Monster SpawnMonster()
            {
                return prototype.clone();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    测试

    			// 创建正常的敌怪 它将作为一个原型对象
                Ghost gp = new Ghost("100");
                // 传入正常的敌怪原型,获得正常的敌怪生成器;如果传入特殊的敌怪原型,即可获得特殊的敌怪生成器
                SpawnerPrototype gsp = new SpawnerPrototype(gp);
                Ghost? gp2 = gsp.SpawnMonster() as Ghost;
    
                gp.attack -= 5;
                Console.WriteLine(gp.attack);
                Console.WriteLine(gp2?.attack);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    还可以使用泛型继续优化

    	// 泛型
        public class SpawnerPrototype2 where T : Monster
        {
            private T prototype;
            public SpawnerPrototype2(T p)
            {
                this.prototype = p;
            }
            public Monster SpawnMonster()
            {
                return prototype.clone();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试

                Demon dp = new Demon("99");
                SpawnerPrototype2 dsp = new SpawnerPrototype2(dp);
                Demon? dp2 = dsp.SpawnMonster() as Demon;
    
    • 1
    • 2
    • 3

    另外,原型也常常用在游戏数据的建模中。

  • 相关阅读:
    php apache 后台超时设置
    Cannot find module ‘./assets/empty-module.js‘
    穿越时空的创新:解析云原生与Web3.0的奇妙渊源
    内网穿透怎么设置?内网映射外网需要注意什么
    C语言:写一个代码,使用 试除法 打印100~200之间的素数(质数)
    阅读笔记——A Frustratingly Easy Approach for Entity and Relation Extraction
    Chrome解决“github.com拒绝了我们的访问请求”
    03、Spring中的静态代理&JDK动态代理&CGLB动态代理
    STM32-按键检测
    【开源】最新仿蓝奏云网盘搜索引擎网站系统源码/蓝搜网页版源码/自适应可二开
  • 原文地址:https://blog.csdn.net/qq_42534809/article/details/126071393