[Unity 代码写法整理]嵌套判断问题(一)

代码中,我们都会把一些可扩展的类抽象出来一层抽象类、基类、接口。子类去重写或者实现这些方法。比方不同平台连接wifi,安卓设备,苹果设备,PC...我们可能会设计一个抽象接口,IConnector,内部写个函数ConnectWifi,然后再写三个类,AndroidConnector,iOSConnector,PCConnector。这样的栗子举到胳膊断了都举不完,这些栗子的 共同点是,他们都是由一个可扩展的类控制。

但是我举这样一个栗子:一个游戏里我们选人物,有两种类型的装备需要选择,第一个是防具,第二个是武器,防具分为皮甲,锁甲,重甲等等,武器分为剑、刀、长矛、锤子等等....需求是:穿戴不同的防具和武器,人物的动画不同。这就是一个典型的嵌套判断问题,也就是说一个事物需要两个类去判断,而且这两个类还可扩展。

==============================

解决这类问题,我目前只能想到以下几种方法,第一章节我想先写一些需要条件判断的,也就是需要if,else,switch的

1.第一种方法是直接在武器类(或者防具类)里通过if、else if、else、switch去判断另一个类型,并实现动作。

interface IWeapon
{
    void playAnimation();
}

public class Sword : IWeapon
{
    public void PlayAnimation()
    {
        if(皮甲)
        {
            //敲代码 动画
        }
        else if(锁甲)
        {
            //不要怂 动画
        }
        else if(重甲)
        {    
            //就是干 动画
        }
        ...
    }
}

这种代码,如果对于我上面的要求,可能显得很搞笑。但是,并不是每一个需要扩展的类都像栗子这样如此的扩展性强。如果其中一个类相对来说扩展性低且数目少,这个做法是绝对可行的,因为只需要在相对扩展性高的那个类里去把另一个扩展性低的类情况列出来即可。

==============================

2.第二种方法是防具类和武器类合二为一,排列组合组成一个更细的类。外层通过if,else if,switch去控制具体使用哪个类。

interface IEquipment    //装备接口,不区分防具和武器
{
    void PlayAnimation();
}

public class LeatherSwordEquipment : IEquipment   //皮甲+剑
{
    public void PlayAnimation()
    {
        //播放动画
    }
}

public class AnimationPlayController
{
    private int armorType;
    private int weaponType;
    private IEquipment equipment;

    public void PlayAnimation()
    {
        if(armorType == 皮甲 && weapontype == 剑)
        {
            equipment = new LeatherSwordEquipment();
        }
        ...
        equipment.PlayAnimation();
    }
}

这种写法的话,假如防具有x种,武器有y种,增加一种防具,增加y个类,增加一种武器,增加x个类,同时还要增加条件判断,反正就是跟各种设计原则都不符。但是如果x和y都相对较少,这种设计方法不失为一种选择,而且这种方法如果出问题,很容易定位。但是相对的,除了需要创建大量的类,更致命的是,毕竟防具和武器都有自己独有的属性,合并在一起仅仅为了动画这一个需求明显不合适。

=============================

3.第三种设计可以说是第一种和第二种设计的结合,首先需要两层的抽象,第一层就是抽象出来装备接口IEquip,第二层是再抽象防具接口和武器接口去继承装备接口,IArmor:IEquip,IWeapon:IEquip。然后,越靠后面出现的装备,就越需要做更多的适配。毕竟我们写装备的类是一个一个写的,那么当前设计的武器,只需要去根据当前已有的防具去播放相应的动作。也就是说,越晚出现的装备,就要去适配更多已有的装备。武器和防具都有播放人物动画的控制权,但是,如果不认识对方,就需要将动画的控制权交给对方。直接上代码

interface IEquipment
{
    void PlayAnimation();
}

public interface IArmor : IEquipment
{
    //Something for Armor
}

public interface IWeapon : IEquipment
{
    //Something for Weapon
}

public class Leather : IArmor
{
    IWeapon currentWeapon;    //此时需要获取到对方的引用
    
    public void PlayAnimation() //皮甲只认识刀
    {
        if(刀)
        {
            //播放动画
        }
        else
        {
            currentWeapon.PlayAnimation();    //这个武器我不认识,动画控制权转交过去
        }
    }
}

public class Sword : IWeapon
{
    IArmor currentArmor;
    public void PlayAnimation()
    {
        if(皮甲)    //由于我比皮甲晚出现,那么我一定认识皮甲
        {
            //播放动画
        }
        else if(锁甲)
        {
            //播放动画
        }
        else
        {
            currentArmor.PlayAnimation();    //我做不到的就留给后人去做了...
        }
    }
}

虽然随着装备的增多,装备的判断会可能会越来越多,但是他居然符合开闭原则,因为我们每一个写好的类,他们都不需要因为新出现的类而做任何的更改。原因就是因为这个else判断,他把控制权转交给自己的子孙。而且,这个设计方式最优秀的地方是,他可以不受维度的限制,比如说,我又多了一个鞋子装备,一个角色带不同的武器,防具,鞋子,播不同的动画。这个设计方式他也能满足要求,因为只要鞋子也继承自IEquipment,那么他们都属于装备这一维度。

==============================

先写这么多吧,欢迎讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值