Могут ли методы объекта действовать на себя? - PullRequest
4 голосов
/ 26 октября 2010

Я не уверен, где поставить некоторые методы.

Допустим, я хочу отправить электронное письмо.

Какой из следующих вариантов я должен выбрать:

email = new Email("title", "adress", "body");
email.send();

или

email = new Email("title", "adress", "body");
Postman.send(email);

Потому что, как электронная почта может отправлять себя? И не лучше ли иметь центральный объект, который обрабатывает все электронные письма, потому что тогда он может регулировать такие вещи, как отправка всех писем в определенное время, сортировка писем, удаление писем и т. Д.

Также, если я хочу удалить пользователя, как мне это сделать:

user.delete();

или

administrator.delete(user);

Пожалуйста, поделитесь своими мыслями о том, как узнать, куда поместить методы.

Ответы [ 5 ]

8 голосов
/ 26 октября 2010

Я не согласен с Арсением.Письмо может отправлять само, и именно здесь должен жить код.Вот что такое методы: действия, которые можно выполнять над объектом.

Однако обратите внимание, что ваши подходы не являются взаимно несовместимыми.Действие send в электронном письме может легко содержать код для добавления себя в очередь отправки Почтальона, и, если вы хотите регулировать действия, это может быть хорошей идеей.Но это не причина, чтобы не использовать метод send для класса электронной почты.

3 голосов
/ 26 октября 2010

Все разумные методы, которые действуют на электронные письма, должны быть в классе электронной почты, для удобства пользователей вашего класса.Но объекты электронной почты не должны содержать никаких полей, кроме тех, которые относятся к содержанию самой электронной почты (принцип единой ответственности).

Поэтому я бы предложил следующее:

class Email
  def email(postman)
    postman.send(self)
  end
end

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

2 голосов
/ 26 октября 2010

Используйте второй метод, чтобы менеджер классов обрабатывал объекты (электронные письма или пользователи). Это следует принципу единственной ответственности.

1 голос
/ 27 октября 2010

Я согласен с Дэниелом.

Следуя вашему первому примеру, у многих распространенных виджетов также есть менеджер "коллекций", как вы упомянули, но это не обязательно.Виджет «Вкладки» может отображать / скрывать одну из своих вкладок, при этом необязательно указывать новый класс вкладок для каждой отдельной вкладки.

Я считаю, что функциональность должна быть заключена в капсулу.Однако пример удаления пользователя - это немного другой случай.Наличие метода delete для класса User может выполнять такие вещи, как очистка его внутренних переменных, настроек и т. Д., Но он не удалит ссылку на себя.Я считаю, что методы удаления лучше подходят для классов на основе коллекции.Я бы не стал ставить метод удаления на класс администратора, а скорее на класс «коллекции» пользователей.

function Users(){
    var users = [];
    this.add = function(user){
        // add user code
        users.push(new User(user));
    }
    this.remove = function(user){
        // remove user code and remove it from array
    }
}

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

1 голос
/ 26 октября 2010

В Ruby я бы сделал это:

email = Email.deliver(recipient, subject, message)

Класс Correpoding будет выглядеть примерно так:

class Email
  def self.deliver(recipient, subject, message)
    # Do stuff to send mail
  end
end

Это чистый и простой в использовании.1008 * По вопросу удаления: удалите объект, который вы хотите удалить.Так что @user.delete будет лучше.Если вы хотите зарегистрировать администратора, который удалил пользователя: @user.delete_by(@admin)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...