【问题标题】:Does Null Object Pattern occupy memoryNull Object Pattern 是否占用内存
【发布时间】:2016-03-05 22:10:32
【问题描述】:

我一直在阅读空对象模式将帮助您避免空检查和空指针异常,从而使您的代码更清晰易懂。

我从未使用过它,我觉得它很有趣。 “null”不会占用内存,但如果我开始用创建“默认”对象来替换我的 null 检查,从长远来看,这个过程会对内存产生负面影响吗?

例如:

空对象模式

public void DoSomething()
{
  User user = this.GetUser(id);
  string strDisplayName = user.DisplayName;
}

public User GetUser(int id)
{
   User user = this.LoadUserFromDB(id);
   if(user ==  null)
      return User.CreateNull();
   return user;
}

所以,我一走出方法的作用域,后面的对象就会被GC回收。 但是如果我在离开作用域之前通过一个循环呢?

public void DoSomething()
{
  users = this.GetAllUsers();
  foreach(User user in users)
  {
     string strAddress = user.Address.StreetName;
     //continue tasks
  }
}

同时在其他班级

public Class User
{
   public Address Address
   {
      get
      {
         if(this.Address == null)
            this.Address = Address.CreateNull();
         return this.Address;
      }
   }
}

public class Address
{
   private string streetName;

   public virtual string StreetName
   {
      get { return this.streetName; }
      set { this.streetName = value; }
   }

   public static CreateNull()
   {
      return new NullAddress();
   }
}

public class NullAddress : Address
{
   public override string StreetName
   {
      get { retun String.Empty; }
   }
}

空检查

User user = this.GetUser(id);
string strDisplayName = String.Empty;
if(user != null)
{
   strDisplayName = user.DisplayName;
}

只需检查用户是否不为空,因此分配属性值。我不会创建“空”对象

提前致谢。

【问题讨论】:

  • 也许只是偏好,但如果是数据库实体,我会考虑使用Optional<User> 而不是“假”用户,因为Optional 保留了“未找到用户”的含义。真正的空对象只有在不会导致正确对象和空替换之间混淆的情况下才能很好地工作(参见Liskov substitution principle)。就像空的 Lists 而不是 null。或者像记录器这样只使用输入的实现。
  • 在 Jon 说应该共享对象的内存问题之外,我不确定编写上游代码以避免破坏下游代码是您想要的方式。正确编写/测试的代码将暴露问题,然后您可以解决根本问题。就个人而言,除非UserAddressStructs(模式说使用User.Empty 之类的东西),否则我会让错误传播并通过编写良好的单元测试来暴露它们。

标签: java c# design-patterns null


【解决方案1】:

通常空对象不是按需创建的,而是共享的。它们通常是其他一些抽象的不可变实现(使用无操作方法或任何合适的方法) - 因此它们可以很容易地共享。

此时,在整个应用程序生命周期中,每个您感兴趣的空对象类型都有一个 单个 对象 - 这几乎肯定是微不足道的。

【讨论】:

    【解决方案2】:

    作为一个模式空对象应该是扁平和纤细的,所以大多数时候答案是否定的。但是你应该警惕那些支持合约序列化的空对象,并且可能会导致到处重复。

    【讨论】:

      猜你喜欢
      • 2016-02-25
      • 2011-09-23
      • 2012-08-10
      • 1970-01-01
      • 2017-11-25
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多