Если только одно поле объекта требуется в методе, что должно быть передано в качестве параметра - объект или значение поля?

Я предпочел бы, чтобы люди записали программное обеспечение, которое является основательным, надежным и делает то, что оно рекламируется, чтобы сделать. То, что они также продают его за разумную цену с разумной лицензией.

я знаю, что потратил впустую слишком много времени, имея дело с поставщиками, которые усложнили лицензирование схем, которые только вызывают проблемы для клиентов и поставщиков. Это всегда - моя рекомендация избежать тех поставщиков. Работа в атомной электростанции, мы вынуждены использовать определенные продукты поставщиков и таким образом вынуждены должными быть иметь дело с их лицензированием схем. Мне жаль, что не было способа возвратить время, когда я лично потратил впустую контакт с их неудачными попытками дать нам, работа лицензировала продукт. На мелочь походит спрашивать, но это, кажется, трудная вещь для людей, которые становятся слишком коварными для их собственной пользы.

7
задан serg 23 October 2009 в 16:26
поделиться

12 ответов

Я не уверен, есть ли «правило» для лучшего, но чаще всего я передаю в метод только нужные мне параметры. Итак, в вашем первом примере я бы передал только book.id, а во втором примере я бы передал только request.getRequestURL ().

Я стараюсь не передавать больше, чем мне нужно.

10
ответ дан 6 December 2019 в 05:55
поделиться

I'm going to be a dissenter and argue for passing the entire Book object.

Reason 1: Type checking. If you just pass an integer ID, there's no way to know, looking at code, if you've got the correct "kind" of integer ID. Maybe you've been passing around an integer variable that you think is the Book ID, but it's actually the Author ID. The compiler is not going to help you catch this mistake, and the results are going to be buggy in unexpected ways.

Reason 2: Future proofing. Some have made the argument that if you just pass the ID, you give yourself the option to change the structure of the Book object later, without breaking the doSomethingWithBook(int ID) method. And that's true. On the other hand, if you pass the entire Book object, you give yourself the option to change the internals of doSomethingWithBook(Book book) (maybe it will want to search based on some other field in the future) without breaking any of the (possibly numerous) places you've called doSomethingWithBook. I'd argue that the latter helps you more.

In the case of the Request, I would give a different answer, since I would consider a Request object to be tightly linked to a certain type of interface (web) and therefore would want to limit the use of that object. One question I like to ask myself: if I wanted to switch this web application to be, say, a command-line application, how many classes would have to change? If I'm passing around the Request, that's going to "infect" more classes with web-specific logic.

7
ответ дан 6 December 2019 в 05:55
поделиться

Более слабое соединение предпочтительнее, если нет особых причин. Если передать идентификатор книги только методу поиска, вы можете изменить интерфейс книги, не беспокоясь о том, что это может повлиять на другие функции. В какой-то момент в будущем вы можете обнаружить, что вам нужно проделать точно такую ​​же работу с некоторым URL-адресом вне обработчика запросов, так что избегать ненужной зависимости от запроса - это хорошо. Но учтите, что если вы часто вызываете do_smth (request.getRequestURL ()) , это может сильно раздражать.

3
ответ дан 6 December 2019 в 05:55
поделиться

Это связано с Законом Деметры , который в основном гласит, что объекты и методы должны получать только то, что им нужно, а не проходить через другой объект, чтобы получить то, что они на самом деле нужно. Если вам нужно использовать несколько полей из Книги в вашем методе, возможно, лучше просто взять книгу. Но в целом у вас будет меньше связи в системе, если вы будете зависеть только от того, что вам нужно.

В обоих ваших примерах, вероятно, предпочтительнее было бы просто использовать ID или URL. В частности, в случае URL-адреса, где (если вы хотите протестировать метод) легко создать URL-адрес для тестирования, но сложнее (и совершенно ненужно) создать запрос для перехода к методу, который затем будет использовать только URL-адрес тем не мение.

3
ответ дан 6 December 2019 в 05:55
поделиться

Я бы дал каждому методу ровно столько, сколько необходимо (поэтому для второго вопроса: просто дайте ему request.getRequestURL () ).

Для первого. Я бы подумал об определении обоих методов (но предпочитаю id -one, поскольку вы можете легко получить идентификатор, если у вас есть Книга, но не наоборот).

findAuthorsForBookId(int bookId)
findAuthorsForBook(Book b)
2
ответ дан 6 December 2019 в 05:55
поделиться

Позвоните book.authors () .

2
ответ дан 6 December 2019 в 05:55
поделиться

(Примечание: это особое мнение относительно принятого ответа.)

Что ж, существует неявный набор правил в контексте моделирования предметной области. Если получатель выполняет задачи независимо от модели предметной области, вы передаете это поле. В противном случае вы должны передать объект, и действие, специфичное для модели, станет явным благодаря тому, что получатель получит доступ к свойству id объекта «Книга». Что наиболее важно, если доступ к свойству когда-либо выходит за рамки простого возврата ссылки на поле (например, определенных действий в инструменте доступа к свойству), тогда, очевидно, вы НЕ хотите преследовать все экземпляры в вашем коде, где вы разыменовали свойство, прежде чем передавать его в различные методы. .

2
ответ дан 6 December 2019 в 05:55
поделиться

На самом деле здесь нет никаких правил, вы должны прямо указать необходимую информацию, в этом случае book.id. Если вы планируете расширить / поделиться своим поиском в будущем, у вас может быть перегруженный метод для приема объекта книги, чтобы вы могли выполнять поиск по другим атрибутам объекта книги.

1
ответ дан 6 December 2019 в 05:55
поделиться

Если вы пишете своего рода DAO, вам следует подумать о наличии BookSelector , который можно создать следующим образом: new BookSelector (). byId (id) .bySomethingElse (somethingElse) и передать этот селектор вместо увеличения числа методов findByXYZ.

0
ответ дан 6 December 2019 в 05:55
поделиться

Подумайте о поддержке кода в долгосрочной перспективе. Любой предлагаемый вами метод - это метод, который вы должны будете поддерживать для своих пользователей в будущем. Если bookId - это все, что нужно в обозримом будущем, я бы просто пропустил это: так любой, у кого есть bookId, сможет использовать ваш метод, и он станет более мощным.

Но если есть большая вероятность, что вам может потребоваться рефакторинг поиска для использования некоторых других атрибутов Book, то переходите в Book.

1
ответ дан 6 December 2019 в 05:55
поделиться

Я согласен с предыдущими постерами. Я хотел добавить, что если вам нужно несколько свойств объекта (id, title, author), я бы предложил передать объект (или интерфейс к объекту). Обычно предпочтительны короткие списки параметров.

0
ответ дан 6 December 2019 в 05:55
поделиться

Lets say there is a method that searches for book authors by book id. What should be passed as a parameter to such method - only book.id (int) or whole book object?

I am making the assumption that "book authors" is an attribute of a book. Therefore, 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 instantiated Book object (aBook), to determine the list of authors, I would expect that I can call aBook.getAuthors(), which requires no parameters.

I would discourage the creation of partially instantiated domain objects. In other words, given a bookid, and looking for a list of authors, I would want the client code to look more like this:

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

and less like this:

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 throwaway objects that are created by the client code. (In this case, bookQuery, which isn't a real book.)

It also makes the code easier to read--and therefore to maintain. This is because bookQuery is not doing what the maintenance programmer would expect. For example, I'd expect two Books with the same ID to have the same tite, authors, ISBN, etc. These assertions would fail for bookQuery and aBook.

Thirdly, it minimizes the chance that you will someday pass an invalid (partially instantiated) Book object to a method that is expecting a real Book. This is a bug where the failure (in the method) may happen far away from the cause (the partial instantiation).

0
ответ дан 6 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: