标签: null-object-pattern

使用空方法的默认实现的设计模式

是否有特定的设计模式描述了提供非抽象默认实现的场景,该实现使用空的NO-OP实现实现接口上的所有或部分方法.这样做的目的是减轻子类的负担,实现他们自己可能不需要/使用的方法:

public interface MyInterface {
    public void doThis();
    public void doThat();
    public void done();
}

public class MyClass implements MyInterface {
    public void doThis() {
        // NO-OP
    }
    public void doThat() {
        // NO-OP
    }
    public void done() {
        // Some standard implementation
    }
}

public class MuSubClass extends MyClass {
    public void doThat() {
        // Subclass only cares about doThat()
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经看到过这种模式多次使用,包括SAX框架中的Java的DefaultHandlerMouseAdapter.在某些情况下,这些类被命名为Adapters,但我的印象是适配器模式在两个不同的接口之间进行转换.

鉴于在这些实例中只有一个声明的接口被转换为该接口的未定义子集 - 我不清楚这是如何在适配器模式的精神.

此外,我不太明白这是如何遵循NullObject模式的,因为某些方法可能有一个实现,而NullObject传统上是一个单例.

design-patterns adapter null-object-pattern solid-principles interface-segregation-principle

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

空对象模式

似乎有越来越多的人说你永远不应该返回null,而应该总是使用Null对象模式.我可以在使用集合/ map /数组或调用boA函数(如isAuthenticated()时看到NOP的有用性,如下所示).

我没有发现任何完全令人信服的东西.当我试图组织我的想法时,请在这里忍受我.

我的理解是,不是返回一个空对象,而是返回一个已被"清零"的有效对象.

因此,例如,客户端将调用以获取对象:

Car car = getCar();
Run Code Online (Sandbox Code Playgroud)

如果不使用NOP,则需要在调用其上的任何方法之前检查从getCar()返回的对象是否为null:

if (car != null){
    color = car.getColor();
    doScreenStuff(color);
   }
Run Code Online (Sandbox Code Playgroud)

使用NOP,getCar()它现在返回一个已被有效"清零"的对象,而不是返回null.所以现在我们不再需要做if (car != null),只能请求颜色.因此,我认为当我们调用颜色时,我们的"归零"对象将返回"无".

这有什么用?似乎向前移动并在空对象上调用方法会导致与仅检查null相同的痛苦.现在,当需要显示信息时,我们需要检查颜色是否为"无",高度不为0,或者您拥有的其他任何值.因此,基本上,如果汽车为空,则不检查处理的开始,而是检查我们拥有的汽车对象是真车还是替代品.IE我们不想显示一堆空对象,所以我们需要一些方法来过滤掉所有空对象.

这个过滤是一个额外的步骤,就像调用if(car!= null)一样.唯一的区别是,通过检查null,我们可以在通过抛出异常发现car对象为null时立即停止处理,而使用NOP我们在空对象上调用方法并继续前进,直到它到达时间为止显示对象,此时我们过滤掉空心.此外,您需要知道空对象返回的值.IE确实getColor()返回"none"或"empty".

显然必须有一些我忽略的东西.提前致谢.

java oop null nullpointerexception null-object-pattern

20
推荐指数
2
解决办法
4812
查看次数

C#中的通用空对象模式

我想知道是否有任何方法在C#中实现通用的空对象模式.泛型null对象是所有引用类型的子类,就像Nothing在Scala中一样.这好像是

public class Nothing<T> : T where T : class
Run Code Online (Sandbox Code Playgroud)

但它无法编译,我不知道如何实现T提供默认行为或抛出异常的方法.以下是一些想法:

  1. 用反射?
  2. 创建时使用表达式树Nothing<T>?它可能看起来像Moq.另一个问题是:在产品代码中使用模拟框架/库是否可以?
  3. 使用动态类型?

我知道也许我应该为特定类型实现特定的null对象.我只是想知道是否有任何解决方案.

有什么建议吗?谢谢.

c# null-object-pattern

16
推荐指数
2
解决办法
2302
查看次数

Ruby类似于nil的对象

如何在ruby中创建一个Object,在类似于nil的逻辑表达式中将其评估为false?

我的目的是在其他对象上启用嵌套调用,其中某个值通常是链的一半nil,但允许所有调用继续 - 返回我的类似nil的对象而不是nil自身.该对象将返回自身以响应任何收到的消息,它不知道如何处理,我预计我将需要实现一些覆盖方法,如nil?.

例如:

fizz.buzz.foo.bar
Run Code Online (Sandbox Code Playgroud)

如果buzz属性fizz不可用,我会返回我的类似nil的对象,它会一直接受调用以bar返回自身.最终,上述陈述应评估为假.

编辑:

根据以下所有优秀答案,我提出了以下建议:

class NilClass
  attr_accessor :forgiving
  def method_missing(name, *args, &block)
    return self if @forgiving
    super
  end
  def forgive
    @forgiving = true
    yield if block_given?
    @forgiving = false
  end
end
Run Code Online (Sandbox Code Playgroud)

这允许一些卑鄙的技巧,如:

nil.forgiving {
    hash = {}
    value = hash[:key].i.dont.care.that.you.dont.exist
    if value.nil?
        # great, we found out without checking all its parents too
    else
        # got the value without checking its parents, yaldi …
Run Code Online (Sandbox Code Playgroud)

ruby metaprogramming null-object-pattern

12
推荐指数
2
解决办法
931
查看次数

Java 记录和空对象模式?

有没有办法用 Java 记录做空对象?对于课程,我会这样做:

public class Id {

  public static final Id NULL_ID = new Id();

  private String id;

  public Id(String id) {
    this.id = Objects.requireNonNull(id);
  }

  private Id() {}
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为每个构造函数都需要经过规范的 ( Id(String id)构造函数,而我不能只是调用super()来绕过不变量。

public record Id(String id) {
  public static final Id NULL_ID = null; // how?

  public Id {
    Objects.requireNonNull(id);
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

现在我解决了这个问题

public Id {
  if (NULL_OBJECT != null)
    Objects.requireNonNull(id);
}
Run Code Online (Sandbox Code Playgroud)

但这感觉不对,并且容易出现并发问题。

我还没有发现很多关于记录背后的设计思想的讨论,这可能已经讨论过了。如果像这样保持简单,那是可以理解的,但感觉很尴尬,我已经在小样本中多次遇到这个问题。

java null-object-pattern java-14 java-record

11
推荐指数
2
解决办法
711
查看次数

C++:返回NULL而不是struct

我有一个结构Foo.在伪代码中:

def FindFoo:
   foo = results of search
   foundFoo = true if a valid foo has been found  

   return foo if foundFoo else someErrorCode
Run Code Online (Sandbox Code Playgroud)

我怎样才能在C++中实现这一目标?

编辑删除了许多不准确之处.

c++ error-handling null-object-pattern

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

得到一个虚拟的slf4j记录器?

我可以从slf4j获得一个虚拟记录器吗?(想想空对象设计模式.)如果是这样,有人可以提供一个例子吗?或者,如果我想这样做,我是否必须实施自定义记录器?

我希望写一个函数

private Logger logger;
static Logger nullLogger;

static {
    nullLogger = getMeADummyLogger();
}

public Logger getLogger() {
    return this.logger == null ? nullLogger : this.logger;
}

// then, elsewhere:
this.getLogger().info("something just happened");
Run Code Online (Sandbox Code Playgroud)

而没有得到NullPointerException,如果没有记录器已被设置在最后一行.

java slf4j null-object-pattern

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

为什么作为 webView2 对象的 coreWebView2 为空?

我正在创建 Microsoft.Web.WebView2.WinForm.WebView2 的对象,但此 coreWebView2 的子对象为空

Microsoft.Web.WebView2.WinForm.WebView2 webView = new Microsoft.Web.WebView2.WinForm.WebView2()
// Change some GUI properties of webView
webView.CoreWebView.NavigateUrl(url)
// I can not access the above line because CoreWebView is null
Run Code Online (Sandbox Code Playgroud)

c# browser invalid-url null-object-pattern webview2

8
推荐指数
5
解决办法
9686
查看次数

具有空对象模式的DAO

阅读后:
有效的Java(参见条款43) - Joshua Bloch
清洁代码(不要返回空) - Bob叔叔
避免!= null语句
Null对象模式

我正在寻找答案,当搜索最终成为非收集对象不存在的实体时,DAO应该返回什么.通过使用空数组或emptyList方法,集合对象确实可以.但是对于非收藏品,它可能会更难.另一种解决方案是永远不会返回null,而是使用Null Object模式.但是我不知道将Null Object模式与DAO集成,我真的很高兴看到与Null Object模式和DAO模式的完美集成,特别是对于模型(dto)对象返回情况.

我将非常感谢并欢迎任何最佳设计模式,场景和建议.

java null dao nullpointerexception null-object-pattern

7
推荐指数
2
解决办法
2878
查看次数

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

最近我遇到了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
查看次数