If a method requires only one field of an object, what should be passed as a parameter - an object or a field value?

Suppose that there is a method for searching for book authors by book identifier. What should be passed as a parameter for such a method - only book.id (int) or the entire book object?

Or another example. In java, I need to do some work with the current URL of the page. What should be passed to this method - only request.getRequestURL () or the whole request?

I see the benefits of each method, but I can’t come up with the right rule when to use what.

Thanks.

+7
java oop
source share
12 answers

I'm not sure if there is a “rule” for the best, but most often I pass only the parameters that I need in this method. Therefore, in your first example, I would only pass in book.id, and in your second example, I would pass only in request.getRequestURL ().

I try to avoid transmitting more than I need.

+10
source share

I am going to be a dissident and argue about transferring the entire subject of the book.

Reason 1: Type checking. If you simply pass an integer identifier, you cannot find out by looking at the code if you have the correct "look" of the integer identifier. You may have walked around an integer variable, which, in your opinion, is the identifier of the book, but actually it is the identifier of the author. The compiler will not help you catch this error, and the results will be erroneous in unexpected ways.

Reason 2: Future check. Some argue that if you simply pass the identifier, you will give yourself the opportunity to change the structure of the book object later without breaking the doSomethingWithBook (int ID) method. And it is true. On the other hand, if you transfer the entire object of the book, you will give yourself the opportunity to change the interior of the doSomethingWithBook (book) (perhaps he will want to look in some other field in the future) without violating any (possibly numerous) places that you called doSomethingWithBook. I would say that the latter helps you more.

In the case of a request, I would give a different answer, since I would consider a Request object that would be closely related to a certain type of interface (web) and therefore would like to limit the use of this object. One question I would like to ask myself: if I wanted to switch this web application to be, say, a command line application, how many classes would I have to change? If I go around a query that is about to “infect” more classes using specific web logic.

+6
source share

A weaker bond is preferred if there is no particular reason. When the travel book ID is used for search purposes only, you can change the book’s interface without worrying that it might affect other features. At some point in the future, you will find that you need to do exactly the same job with some external request handler, so avoiding unnecessary dependency on the request is good. But note that if you often call do_smth(request.getRequestURL()) , this can become quite annoying.

+3
source share

This is due to the Law of Demeter , which basically says that objects and methods should only get what they need, and not go through another object to get what they really need. If you need to use several fields from Book in your method, it is best to just take a book. But in general, you will have less grip in the system if you depend only on what you need.

In both examples, it is probably preferable to use an identifier or URL. In particular, in the case of a URL where (if you want to test the method), it’s easy to create a URL for testing, but it’s harder (and completely unnecessary) to create a request to go to a method that will only use the URL so or otherwise. This method is also more widely applicable to other situations than the one in which you have a request object.

+3
source share

I would give each method only as much as necessary (so for the second question: just give it request.getRequestURL() ).

For the first, I would think about defining both methods (but I prefer id -one, since you can easily get the identifier if you have a book, but not vice versa).

 findAuthorsForBookId(int bookId) findAuthorsForBook(Book b) 
+2
source share

Call book.authors() .

+2
source share

(Note: this is a dissenting opinion regarding the accepted answer.)

Well, there is an implicit rule set in the context of domain modeling. If the recipient performs the job regardless of the domain model, you pass this field. Otherwise, you must pass the object, and the specific action of the model becomes the explicit action of the actor who gains access to the id property of the Book object. Most importantly, if access to property ever evolves beyond simply returning a link to a field (for example, certain actions in the property accessory), then obviously you DO NOT want to chase all instances of your code where you dereferenced the property before passing it various methods.

Further considerations are the consequences (if any) of accessing the field before calling cite or inside the receiver.

+2
source share

There is really no rule, you should be clear with the information you need, in this case book.id. If you plan to extend / share your search in the future, you may have an overloaded method to accept a book object so that you can search for other attributes of the book object.

+1
source share

Consider saving code in the long run. Any method that you disclose is a method that you will need to support for your users in the future. If bookId is all that is needed for the foreseeable future, then I would just pass by: in this way, anyone who has a book can use your method, and it becomes more powerful.

But if there is a good chance that you may need to reorganize the search to use some other attributes of the Book, then go to the book.

+1
source share

If you are writing DAO varieties, you should consider having a BookSelector that you can create, for example: new BookSelector().byId(id).bySomethingElse(somethingElse) , and pass this selector instead of having findByXYZ methods.

0
source share

I agree with the previous posters. I would like to add that if you need several properties of an object (id, title, author), I would suggest passing an object (or an interface to the object). Short lists of options are usually preferred.

0
source share

Suppose that there is a method for searching for book authors by book identifier. What should be passed as a parameter for such a method - only book.id (int) or the entire book object?

I make the assumption that "book authors" are an attribute of the book. So I imagine something like the following class:

 class Book { private int id; private List<Author> authors; // ... maybe some other book information public int getID() { return this.id } public void setID(int value) { this.id = value } public List<Author> getAuthors() { return this.authors.clone(); } // ... } 

Given an instance of the Book ( aBook ) object to determine the list of authors, I would expect that I can call aBook.getAuthors() , which does not require any parameters.

I would refuse to create partially created domain objects. In other words, given bookid and searching for a list of authors, I would like the client code to look like this:

 Book aBook = library.findBook(bookid); List<Author> authors = aBook.getAuthors(); 

and less:

 Book bookQuery = new Book().setID(bookid); // partially instantiated Book Book aBook = library.findBook(bookQuery); List<Author> aBook = book.getAuthors(); 

The first version reduces the number of excluded objects created by client code. (In this case, bookQuery , which is not a real book.)

It also makes it easier to read code - and therefore its support. This is because bookQuery does not do what the maintenance programmer expects. For example, I expect that two books with the same identifier will have the same type, authors, ISBN, etc. These statements will fail for bookQuery and aBook .

Third, this minimizes the likelihood that you will ever pass an invalid (partially instance) Book object to a method that expects a real Book. This is a mistake in which a failure (in a method) can occur far from the cause (partial implementation).

0
source share

All Articles