【问题标题】:Delegation vs exposing properties委托与公开属性
【发布时间】:2015-01-27 18:31:41
【问题描述】:

我正在查看类中类似外观的委托,例如,假设您有 Equipment 类(使用 Equip() 和 UnEquip() 方法),然后您有一个 Player 类,它引用了 Equipment .

我实现 Player 类的方式是使用一些公共方法,例如 EquipItem 和 UnEquipItem,这些方法会将任务委托给 Equipment 类。现在,如果玩家也有另一个做事的类,比如运动,那么我会再次在 Player 类上放置一些公共方法,以类似外观的方式委托给运动类。现在,外观模式的缺点之一是它处理的类或系统越多,接口就越多。并且假设我知道在未来,Player 类将拥有更多功能。

我不知道这是否是正确的方法,但我在想是否可以将设备和运动引用公开为属性,如下所示:

Class Player
{
     public Equipment equipment { get; set; }
     public Movement movement { get; set; }
}    

现在,我知道暴露对象的状态是不好的,但是这样你就可以更好地控制类的不断增长的接口,并且在 Player 类上有更多的重点方法。所以而不是:

player.Equip();

你可以的

player.equipment.Equip();

最后,我的问题是在这种情况下最好的方法是什么,或者我有什么问题?谢谢

PS:示例来自游戏领域,但解决方案不一定适用于游戏,我只是认为它易于理解。

【问题讨论】:

  • 请注意,属性在技术上并不公开状态,它们只是方法(如其他语言中的 getX/setX 方法)。
  • 该类不是static 那么您在哪里实际实例化Player 类的实例..?阅读C# Basics Tutorials
  • 就个人而言,我会采用完全不同的方法来解决这个问题。我不会将 Movement 作为玩家属性的一部分,但也许有一个 Game 类,它将负责游戏中玩家的移动。
  • @MathodMan 哦,对不起,这个类不是静态的,只是为了演示目的,我只是想用尽可能少的代码来表达这个想法,这样更容易理解
  • @YuvalItzchakov 你是对的,但请注意,我并没有期望在游戏方面有一个正确的解决方案,我试图传达的是在你的公共界面会增长退出的情况下你会做什么一点点。以及您将如何访问它。

标签: c# design-patterns


【解决方案1】:

另一种方法是开发一组命令动作,这些动作可以应用于操纵状态的玩家。虽然命令对象可以扩展对播放器的访问权限,但外部 API 会将实现细节保留为黑匣子。

举个例子:

public abstract class Action 
{
   public abstract void ActOn(Player player);
}

public class EquipAction : Action 
{
    private Item item;
    public EquipCommand(Item item) {
      this.item = item;
    }

    public void ActOn(Player player) {
       player.Equipment.Add(item);
    }
} 

public interface IPlayer
{
    void PerformAction(Action action);
}

public class EquipmentSet
{
    public List<Item> Items { get; private set;}
} 

public class EquipmentManager
{
    public Add(Item item) {
    }

    public List<Item> Items { get; }
}

public class Player : IPlayer
{
    public EquipmentManager manager;

    public PerformAction(Action action) {
       action.ActOn(this);
    }

    public List<Items> Equipment {
       return manager.Items;
    }
}

现在显然,要让它完全能够做你想做的事,还有很多工作要做,但想法是将你的公共界面限制为你想要公开的结构(例如属性、设备) , status, .etc) 并将所有动词委托给动作。

实际上,播放器的实际功能可以分解为尽可能多的组件,以限制每个组件的大小。

【讨论】:

  • 很有趣,所以不是直接作用于播放器的对象,而是通过命令间接访问它(并且您仍然决定公开属性以访问类实例)。唯一让我担心的是,这样你必须为每个不同的命令创建一个类(例如一个用于 Equip() 和一个或 Unequip(),对吗?)。那么这会是一个升级到很多命令的问题吗?管理中大数量是否可以接受?
  • 虽然您可以在系统中拥有大量命令,但如果您花时间对它们进行逻辑分组,那么跟踪单个命令将比一个对象上的大型 API 更容易。此外,通过正确的测试策略,每个命令都可以独立测试,这将使您的系统更容易保持正确运行,并且副作用更少。
猜你喜欢
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2014-02-09
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多