1

Suppose we have Book class which contains year_published public field. If I want to implement NullObject design pattern, I will need to define NullBook class which behaves same as Book but does not do anything.

Question is, what should be the behavior of NullBook when it's fields are being assigned?

Book book = find_book(id_value);  //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016;  //What should we do here?!
Mahdi
  • 1,871
  • 2
  • 24
  • 41
  • May you should start by not accessing directly the properties (define them as private) and use setter. So you can control what value you assign at your class. – olibiaz Sep 13 '16 at 02:10
  • But generally that's not always possible. – Mahdi Sep 13 '16 at 02:15
  • Also, you can assume the code is inside one of class methods. So it will have access to private fields too. – Mahdi Sep 13 '16 at 02:16

2 Answers2

1

The first thing you should do is to make your properties private.

class NullBook {
    private year_published;
    // OR solution2 private year_published = null;

    public setYearPublished(year_published) {
        this.year_published = null;
        // OR solution2 do nothing!
    }
}

You can also define the field private in the parent class, so the children will have to implement the setter to acces the field

class Book {
  private year_published;

  public setYearPublished(year_published) {
     this.year_published = year_published;
  }
}

class NullBook extends Book {
    public setYearPublished(year_published) {
        parent::setYearPublished(null);
    }
}

Why use getters and setters? https://stackoverflow.com/a/1568230/2377164

Community
  • 1
  • 1
olibiaz
  • 2,551
  • 4
  • 29
  • 31
  • What if the code is inside one of class methods which has access to private fields too? – Mahdi Sep 13 '16 at 02:16
  • Just suppose that the sample code in the question is inside a class method (so it has access to private fields too). This means that, even if fields are marked as private, the issue will still persist. – Mahdi Sep 13 '16 at 02:22
  • inside a class method of NullBook? Then you are the developer of the class, implement it right to avoid that someone from "outside" your class set your field with another value than null. Use the setter every time you need to write the field. I don't see the problem, maybe i misunderstand what you mean. – olibiaz Sep 13 '16 at 02:29
  • So the only way we can make use of NullObj pattern is to have no public fields. right? – Mahdi Sep 13 '16 at 02:49
  • The only way is to control how the field is set, so its to have a setter that can control, so putting the property private is the only way i can see so far. – olibiaz Sep 13 '16 at 02:50
1

Thing is: patterns are about balancing. Yes, it is in general good practice to not return null, but to having else to return; but well: what is returned should still make sense!

And to a certain degree, I don't see how having a "NullBook" really helps with the design of your application. Especially as you allow access to various internal fields. You exactly asked the correct question: what should be the published year, or author, or ... of such a "NullBook"?! What happens for example when some piece of code does a "lookup" on books from different "sources"; and then tries to sort those books on the published year. You sure don't want your NullBook to ever be part of such data.

Thus I fail to see the value in having this class, to the contrary: I see it creating a potential for "interesting" bugs; thus my answer is: step back and re-consider if you really need that class.

There are alternatives to null-replacing objects: maybe your language allows for Optionals; or, you rework those methods that could return null ... to return a collection/array of books; and in doubt: that list/array is simply empty.

Long story short: allowing other classes direct access to private fields is a much more of an import design smell; so you shouldn't be too focused on NullObjects, while giving up on such essential things as Information Hiding so easily on the other hand.

GhostCat
  • 137,827
  • 25
  • 176
  • 248