工厂模式+1

来源:互联网 发布:mac能玩的大型网游 编辑:程序博客网 时间:2024/06/07 06:04

为了更好的理解工厂模式,写了一个游戏中常用的例子:敌人死亡后的物品掉落。

如果直接在敌人死亡后,采用if-else或者switch的方法决定掉落对象,也可以实现这项功能。这样,敌人所依赖的具体物品就太多了,而且只会越来越多。这时,如果物品的具体实现变了,你还要找到敌人掉落物品这段代码进行修改。其实如果结构理想,我们不论怎么修改物品的实现,都不应该影响到敌人里面的代码。之所以出现这种情况,就是因为敌人相对于物品是高级组件,而我们让高层组件依赖了底层组件(物品)。这就是所谓的依赖倒置。再说直白点:敌人的代码和物品的实现耦合了。试想一下,如果这个地方,敌人掉落物品,依赖的是抽象物品而不是具体物品,那一切问题是不是迎刃而解了?

直接上代码:

public abstract class ItemFactory    {        public abstract Item CreateItem();    }    public class ClothFactory : ItemFactory    {        public override Item CreateItem()        {            return new Cloth();        }    }    public class MeatFactory : ItemFactory    {        public override Item CreateItem()        {            return new Meat();        }    }    public class Item    {    }    public class Cloth : Item    {            }    public class Meat : Item    {            }    public abstract class Enemy    {        public abstract Item GetItem();    }    public class Person : Enemy    {        ClothFactory clothFactory;        public Person(ClothFactory clothFactory)        {            this.clothFactory = clothFactory;        }        public override Item GetItem()        {            return clothFactory.CreateItem();        }    }    public class Animal : Enemy    {        MeatFactory meatFactory;        public Animal(MeatFactory meatFactory)        {            this.meatFactory = meatFactory;        }        public override Item GetItem()        {            return meatFactory.CreateItem();        }    }
首先,抽象工厂方法设定,所有物品工厂必须提供一个实例化自己物品的方法,并提供返回值。

布工厂生产 布的实例,肉工厂生产肉的实例。(我们假设敌人掉落布和肉两种物品)

抽象敌人设定,所有敌人必须提供掉落物品方法,并提供返回值。

人型敌人使用布工厂,这样,人型敌人掉落方法里生产的就是布。

而动物敌人使用肉工厂,他的掉落方法里产生的自然就是肉。

这样。什么样的敌人想掉什么样的东西,自由组合就好了。而且是由子类自己决定掉什么东西。超类(Enemy)不关心也不知道掉什么,只知道掉了东西就好了(及时掉出来的是空,也就是不掉东西)。

这样,不管是敌人还是工厂,依赖的都是抽象(Item),他们之间的联系也是通过抽象建立起来的。在这种结构下,无论每部分做什么样的修改,都不会影响到别的部分,维护起来就放心多了。
PS:这个抽象工厂里不正包含着简单工厂么?

再废一句话:简单工厂通过重写对客户与实例化解耦,抽象工厂通过对象组合对客户与实例化解耦。

原创粉丝点击