Forgotten design Patterns-null object pattern

Source: Internet
Author: User

    GoF(四人帮)那本《设计模式 可复用面向对象软件的基础》可谓是设计模式方面的经典之作,其中介绍的23种设计模式,也可谓是经典中的经典。但是,设计模式的种类绝不仅仅是这23种,除此之外还有很多巧妙可爱的设计模式值得我们学习。这些被遗忘的设计模式,也可以堪称经典之作。今天我们来一起学习被遗忘的设计模式——空对象模式(Null Object Pattern)。一起看看这个模式会带给我们怎样的惊喜?
First, Pattern name

Provide an object as a surrogate for the lack of an object of a given type. The Null Object provides intelligent do nothing behavior, hiding the details from its collaborators.

Second, problem

Any design pattern without a real-world scenario is in bullying. Learning design patterns, not only to understand its essence, but also to use in the practice of design, to adapt, let's see, under what circumstances, this null Object pattern will come in handy?

Suppose such a scenario:

In a library information query system, you call a method that passes through the ID of the book you want to find, and then it returns you to the book object you're looking for, so you can call the object's method to output the book's information.

I think this kind of scenario is quite common in programming. Below, let's implement the following specific code.

First, let's look at the code for the Concretebook Class (the show () method that provides the constructor and the display of the book information. ):

 Public  class concretebook {    Private intID;PrivateString name;PrivateString author;//Constructors     Public Concretebook(intID, string name, string author) { This. id = ID; This. name = name; This. Author = author; }/** * * Description about Show: <br> * information on displaying books * * @version V1.0 * *     Public void Show() {System.out.println (ID +"**"+ name +"**"+ author); }}

Let's take a look at the code for the book factory that created the book object (mainly providing a way to get Concretebook):

 Public  class bookfactory {    /** * * Description about GetBook: <br> * Get the book object based on the ID of the Concretebook. * @param ID book ID * @return Book Object * @version V1.0 * *     PublicConcretebookGetBook(intID) {Concretebook book =NULL;Switch(ID) { Case 1: Book =NewConcretebook (ID,"design mode","GoF"); Break; Case 2: Book =NewConcretebook (ID,"Forgotten Design Patterns","Null Object Pattern"); Break;default: Book =NULL;//Actually this can be omitted, because initialization has been assigned a value of NULL.              Break; }returnBook }}

Finally, take a look at the client's code:

publicclass Client {    staticvoid main(String[] args) {        new BookFactory();        ConcreteBook book = bookFactory.getBook(1);        book.show();    }}

The above three pieces of code is very simple, I will not do a detailed explanation. Below, let's run it and the results are as follows:

Well, run very smoothly, at this time, we put Concretebook book = Bookfactory.getbook (1), 1 to 2, EN, also run successfully. At this time, we changed to-1. To run again, found the following error:

Null pointer error, yes, this should be the Java beginner to see the most error. It prompts us the 28th line Book.show () error. What is this for? Because when we get the Concretebook object through the Bookfactory.getbook () method, if we pass in the parameter, that is, the ID of the book, is an illegal value (such as-1) or does not exist (such as 3) (in fact, this situation is often encountered.) ), NULL is returned, indicating that the book information we are looking for does not exist. At this point, book is null. You call Book.show () again. Of course it's wrong to quote a null pointer. How to solve it?

Our usual practice is to add a judgment to the client to determine if it is null. If NULL, the show () method is no longer called. If not NULL then call the show () method. The changes are as follows:

publicstaticvoidmain(String[] args) {        new BookFactory();        ConcreteBook book = bookFactory.getBook(-1);        //判断book对象是否为null。        ifnull) {            System.out.println("book对象为 null。");        else {            book.show();        }    }

At this time, run again, there will be no error. Instead, the output: The book object is null.

But have you ever thought about it? Doing so does eliminate the error, but is it really good? Do you think if there are many places in a program called the Getbook () method or a lot of clients (more than the library of the query terminal is certainly more than one AH), not many places to determine whether the book object is NULL? This is not bad, if there is no judgment, and then error, it is likely to cause the program can not continue to run or even crash. And, you have to remember, never too much trust the client, not the stability of the entire program pinned to the client. Also, like the above processing method, when the object is null, the output of the prompt message is a client to customize, so it is not the initiative to the client, not our system itself?

How exactly should it be done to be more appropriate? It's going to use the null Object we're going to be using today. pattern--A forgotten design pattern

Third, Solution

First, let's look at the UML class diagram structure of the null Object pattern:

This class diagram structure is still very simple, the realobject in fact is equivalent to our Concretebook class, and Nullobject is we will add the empty object class, and the Abstractobject class is the parent class we want to raise. We just added a bookfactory between the client and the Abstractobject.

Here, let's change our code:

New abstract interface for the book Class Code:

interface Book {    // 判断Book对象是否为空对象(Null Object)    publicisNull();    // 展示Book对象的信息内容。    publicvoidshow();}

New empty object class Nullbook class code (Inherit book Class):

publicclass NullBook implements Book {    publicbooleanisNull() {        returntrue;    }    publicvoidshow() {    }}

The original Concretebook class modified code (to increase the implementation of the book Interface, the implementation of the IsNull method):

 Public  class concretebook implements book {    Private intID;PrivateString name;PrivateString author;//Constructors     Public Concretebook(intID, string name, string author) { This. id = ID; This. name = name; This. Author = author; }/** * * Description about Show: <br> * information on displaying books * * @version V1.0 * *     Public void Show() {System.out.println (ID +"**"+ name +"**"+ author); } Public Boolean IsNull(){return false; }}

The factory class (Bookfactory) modifies the code (returns the object from Concretebook to book, and returns the Nullbook object when the ID belongs to an illegal value or does not exist. ):

 Public  class bookfactory {    /** * Description about GetBook: <br> * Gets the book object based on the ID of the Concretebook. * @param ID book ID * @return Book Object * @version V1.0 * *     PublicBookGetBook(intID) {book book;//Change the original Concretebook to book        Switch(ID) { Case 1: Book =NewConcretebook (ID,"design mode","GoF"); Break; Case 2: Book =NewConcretebook (ID,"Forgotten Design Patterns","Null Object Pattern"); Break;default: Book =NewNullbook ();//Create a Nullbook object             Break; }returnBook }}

The code for the client is:

    publicstaticvoidmain(String[] args) {        new BookFactory();        Book book = bookFactory.getBook(-1);        book.show();    }

Running, we find that even if the passed parameter is an illegal value or a nonexistent value, it does not give an error, which is the first benefit of the null Object pattern. But now no error, there is no output, certainly not friendly enough, not humane. In this case, in the Show method of the Nullbook class, we can customize our output reminders to output our custom reminders when the user calls the show method of an empty object. This time we can achieve, a custom, everywhere output, the initiative in our hands, not in the hands of the client. This is a second benefit of the null Object pattern.

For example, we make the following changes, the modified Nullbook class code:

publicclass NullBook implements Book {    publicbooleanisNull() {        returntrue;    }    publicvoidshow() {        System.out.println("Sorry,未找到符合您输入的ID的图书信息,请确认您输入的不是非法值。");    }}

At this point, after executing the client, you will find that the console output is: Sorry, the book information that matches the ID you entered is not found, make sure that you are not entering an illegal value.

In fact, although we do not test at the client can also ensure that the program does not error, but the best way, or to carry out the corresponding detection, as follows:

    publicstaticvoidmain(String[] args) {        new BookFactory();        Book book = bookFactory.getBook(-1);        if (book.isNull()) {            //这里由客户端定制提醒代码            System.out.println("兄弟,你输入的ID不符合规范吧。");        }else{            book.show();        }    }

We see in contrast that Book.isnull () is a little more elegant than book = = null. Here, the Null Object pattern is about to be introduced. As we can see, the fact that the null Object pattern is still somewhat interesting can be said to make the whole system more robust.

Iv. Consequences

The Null Object pattern, as a forgotten design pattern, has a role that cannot be forgotten.

(1) It can strengthen the stability of the system, can effectively prevent the error of NULL pointer to the whole system, make the system more stable.
(2) It can realize the custom control of the empty object situation, and can grasp the initiative to deal with the empty object.
(3) It does not rely on the client to ensure the stable operation of the whole system.
(4) It is more elegant and more understandable by IsNull's replacement of ==null.

v. Summary

Here, our null Object pattern is finished, you can also refer to this information, but also speak very good. http://www.cs.oberlin.edu/~jwalker/nullObjPattern/

Forgotten design Patterns-null object pattern

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.