标签: null-object-pattern

空对象模式以避免空检查?

最近我遇到了Null Object设计模式,我的同事说它可以用来取消整个代码中遇到的空指针检查.

例如,假设DAO类返回有关Customer的信息(在名为CustomerVO的值对象中).我的主要课程应该提取firstName和emailId并向客户发送电子邮件.

...
CustomerVO custVO = CustomerDAO.getCustomer(customerID);
if(custVO != null) { // imp, otherwise we may get null ptr exception in next line
     sendEmail(custVO.getFirstName(), custVO.getEmailID());
}
...
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的示例,但是这样的空检查可以根据值对象的复杂性快速传播到整个代码中.

我有两个与null检查的问题, - 它们倾向于使代码变得丑陋且难以阅读 - 经验较少的开发人员在实际上应该抛出异常时进行不必要的空检查.例如,在上面的代码中,最好从getCustomer()本身抛出异常,因为如果它无法找到给定CustID的客户信息,则表明CustID无效.

好吧,回到null对象模式,我们可以使用'null'CustomerVO对象隐藏空检查吗?

CustomerVO {
   String firstName = "";
   String emailID = ""; 
}
Run Code Online (Sandbox Code Playgroud)

这不是有意义的.你怎么看?

为了最大限度地减少应用中的空值检查,您遵循了哪些内容.

design-patterns null-object-pattern

6
推荐指数
1
解决办法
2579
查看次数

空对象设计模式问题

我最近在Null对象设计模式上观看了这个youtube教程.即使它有一些错误:例如NullCar没有做任何事情会产生无限循环,这个概念得到了很好的解释.我的问题是,当可以为null的对象具有getter并在代码中使用时,您会怎么做?你怎么知道默认返回哪个值?或者我应该在所有对象中实现此模式?如果我需要返回字符串或基元怎么办?我是从Java角度谈论的.

编辑:我不会交易空对象测试默认值测试?如果没有,为什么不呢?

java design-patterns null-object-pattern

5
推荐指数
2
解决办法
7081
查看次数

我更喜欢哪种模式?

在我们的项目中,我们需要存储一些对象(例如User),并且User类必须有一个验证标志(setOutdated和isOutdated等方法)

有时,我们的User对象可能为null,但在这种情况下必须可以访问验证标志.可以从User类中提取这些方法,但由于语义的原因,该字段和方法必须位于该类中.

我发现了一些关于Null Object模式的文章(像这样),我想知道 - 是否可以创建Null Object(作为模式),它可以存储多个状态,如null过时,null不过时,不过时和过时不是没有过时的.

PS:如果在我的类中引入"过时"字段,则很难清除对象而不是将其设置为null

java null design-patterns null-object-pattern

5
推荐指数
1
解决办法
157
查看次数

Rails中关联的空对象模式

尽管在这里看到一些关于轨道中的Null对象的答案,我似乎无法让它们工作.

class User < ActiveRecord::Base
  has_one :profile
  accepts_nested_attributes_for :profile

  def profile
    self.profile || NullProfile #I have also tried
    @profile || NullProfile #but it didn't work either
  end
end

class NullProfile
  def display #this method exists on the real Profile class
    ""
  end
end

class UsersController < ApplicationController
  def create
    User.new(params)
  end
end
Run Code Online (Sandbox Code Playgroud)

我的问题是在用户创建时,我为配置文件传递了适当的嵌套属性(profile_attributes),最后我的新用户使用了NullProfile.

我猜这意味着我的自定义配置文件方法在创建时被调用并返回NullProfile.我如何正确地执行此NullObject,以便这仅在读取时发生,而不是在对象的初始创建时发生.

null-object-pattern ruby-on-rails-3

5
推荐指数
1
解决办法
1450
查看次数

Rails中的空对象的命名约定?

对于Rails应用程序:是否存在用于命名映射到模型对象的空对象的命名约定?

例:

#app/models/blog.rb
class Blog < ActiveRecord::Base
end

#app/models/null_blog.rb
class NullBlog # Null Objects are POROs, correct?
  def title
    "No title"
  end
end

# so to implement it I can do this:
blogs = ids.map{|id| Blog.find_by(id: id) || NullBlog.new}
# which allows me to do this and it works, even if some of those ids did not find a blog
blogs.each{|blog| blog.title}
Run Code Online (Sandbox Code Playgroud)

NullBlog传统的吗?

无论这篇文章Avdi格林还是没有什么东西呈现由三弟梅斯提到的任何空对象命名约定。

ruby ruby-on-rails null-object-pattern

5
推荐指数
1
解决办法
103
查看次数

Rails text_field / text_ara 空字符串与 nil

我什至不确定我是否有问题,但我只是不喜欢我的 text_fields 和 text_areas 保存在数据库中而empty string不是nil.

我正在使用空对象模式,刚刚意识到如果我创建一个配置文件但不填写位置字段然后调用<%= @user.profile.location.upcase %>它就不会爆炸,因为位置是一个字符串,即使它是空的。

这是 Rails 的惯例吗?如果是这样,那为什么呢?这有点奇怪,因为假设个人number_of_pets资料上有一个 attr,然后我尝试调用类似的东西

<% if user.profile.number_of_pets.odd? %>
  <%= @user.profile.first_name %> has odd number of pets
<% end %>
Run Code Online (Sandbox Code Playgroud)

然后事情就爆发了,因为我无法打电话nil.odd?

形式如常,所以如果不填写,将保存为空字符串

<%= form_for @profile, url: user_profile_path do |f| %>
  <%= f.label :city %>
  <%= f.text_field :location, class: 'form-control' %>
  ......
Run Code Online (Sandbox Code Playgroud)

database null ruby-on-rails null-object-pattern

5
推荐指数
1
解决办法
3910
查看次数

Fowler Null对象模式:为什么要使用继承?

为什么Fowler PoEAA p.498以下列方式定义空对象模式(示例缩短,语言为c#但无关紧要):

public class Customer
{
  public virtual string Name {get; set;}
}

public class NullCustomer : Customer, INull
{
  public override Name 
  {
     get { return "ImTheNull";}
     // setter ommitted
  }
}
Run Code Online (Sandbox Code Playgroud)

INull用作标记界面.我不喜欢这种方法有三个原因:

  1. 属性需要标记为虚拟
  2. 我不能再密封我的实体课了
  3. 引入至少(n + 1)个新类型(n个空对象,一个标记接口)

为什么不像这样实现:

public class Customer
{
  public static readonly Customer NullCustomer = new Customer(){Name = "ImtTheNullCustomer";}

  public string Name {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

我一般都认为福勒的所有例子都经过深思熟虑,显然我必须在这里找到一些东西.

design-patterns null-object-pattern poeaa

4
推荐指数
1
解决办法
1603
查看次数

可以将null插入Cache吗?

我在ASP.NET网站中主动使用缓存.

但是,db请求的某些对象确实不存在.例如,我Discount通过ProductId=@ProductIdProductsDiscount表中查看记录来检查特定产品是否存在.没有记录意味着没有折扣.

你认为将null折扣对象放入缓存是一个好主意吗?

或者我会更好地发明一些东西(例如使用空对象模式).事实上,我真的不喜欢开始使用null-object模式的想法,因为它需要进行大量的重新设计,我现在至少要避免.

谢谢.欢迎任何想法.

PS实际上,当我尝试调用时,我甚至无法将null对象放入Cache中:

HttpContext.Current.Cache.Insert("name...", null);
Run Code Online (Sandbox Code Playgroud)

我收到:

值不能为空.

PPS为什么MSDN对此行为一无所知?

c# asp.net caching design-patterns null-object-pattern

2
推荐指数
1
解决办法
2242
查看次数

用反射创建对象

我正在尝试编写一个NullObject创建方法,在其中传入一个实现ICreateEmptyInstance接口(即为空)的类名,并且它遍历它的属性,寻找实现的其他类,ICreateEmptyInstance并将创建那些的"Null"实例.

public interface ICreateEmptyInstance { }

public static class NullObject
{
    public static T Create<T>() where T : ICreateEmptyInstance, new()
    {
        var instance = new T();

        var properties = typeof(T).GetProperties();
        foreach (var property in properties.Where(property => typeof(ICreateEmptyInstance).IsAssignableFrom(property.PropertyType)))
        {
            var propertyInstance = NullObject.Create<property.PropertyType>();
            property.SetValue(instance, propertyInstance);
        }

        return instance;
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该可以用它来称呼它

var myEmptyClass = NullObject.Create<MyClass>();
Run Code Online (Sandbox Code Playgroud)

我遇到问题的地方是在foreach循环中,有了这一行

var propertyInstance = NullObject.Create<property.PropertyType>();
Run Code Online (Sandbox Code Playgroud)

...显然这不起作用,但我怎样才能完成创建"空对象"以分配给我正在创建的实例.

编辑:那么泛型呢?我想创建空实例

  foreach (var property in properties.Where(property => property.GetType().IsGenericType))
  {
       var propertyInstance = Enumerable.Empty<>(); //TODO: …
Run Code Online (Sandbox Code Playgroud)

c# reflection null-object-pattern

2
推荐指数
1
解决办法
164
查看次数

如何在 Kotlin 中的数据类上实现空对象模式?

我有一个 Kotlin 数据类:

data class PaymentAccount(
    val accountId: Int,
    val accountNumber: String,
    val title: String
)
Run Code Online (Sandbox Code Playgroud)

这就是我在 Java 中所做的:

创建一个抽象类:

public abstract class PaymentAccount {

    protected int accountId;
    protected String accountNumber;
    protected String title;

    public PaymentAccount(int accountId,
                          String accountNumber,
                          String title) {
        this.accountId = accountId;
        this.accountNumber = accountNumber;
        this.title = title;
    }
}
Run Code Online (Sandbox Code Playgroud)

创建空对象并扩展抽象类:

public class NullPaymentAccount extends PaymentAccount {

    public NullPaymentAccount() {
        super(-1,
                "Invalid account number",
                "Invalid title");
    }
}
Run Code Online (Sandbox Code Playgroud)

创建一个真实的对象并扩展抽象类:

public class RealPaymentAccount extends PaymentAccount {

    public RealPaymentAccount(int …
Run Code Online (Sandbox Code Playgroud)

design-patterns null-object-pattern kotlin

1
推荐指数
2
解决办法
3819
查看次数

实现空对象模式

我发现这个问题以某种方式在 Kotlin 中实现了空对象模式。我通常在 Java 中做一些不同的事情:

class MyClass {
    static final MyClass INVALID = new MyClass();

    public MyClass() {
       // empty
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,我就可以随时将MyClass.INVALID其用作空对象。

如何在 Kotlin 中实现这种风格?

我摆弄了这样的事情:

data class MyClass(val id: Int) {
    object INVALID: MyClass {
    }
}
Run Code Online (Sandbox Code Playgroud)

但这甚至无法编译。

null-object-pattern kotlin

1
推荐指数
1
解决办法
313
查看次数

使用Null对象模式时检查无效状态

使用Null Object模式时,如果情况无效,您将如何"检查"?例如,当存储库中找不到任何项目时,向用户显示"未找到"消息.

我必须做一个美化的空检查吗?

  1. if obj.equals(new NullObject()){showNotFound(); }
  2. if obj.ID.equals(INVALID_ID){showNotFound(); }

这些技术似乎打败了Null Object模式本身的目的

c# design-patterns null-object-pattern

0
推荐指数
1
解决办法
627
查看次数