Объекты Collaborator в ООП

В учебной программе Launch School 120: объектно-ориентированное программирование говорится, что использование объектов-соавторов лежит в основе объектно-ориентированного программирования. Учитывая это, я был удивлен тем, насколько сложно было найти краткое определение, которое могло бы точно сказать мне, что такое объект соавтора?

Если вы определите объект соавтора в Google, первый возвращенный результат - это блог, ссылающийся на учебную программу Launch School, а следующие лучшие результаты сразу переходят к подробному обсуждению карточек CRC, но не имеют четкого и согласованное определение для объектов-соавторов. Интересно, что создатели карточек CRC заявили, что инструменты были разработаны именно из-за трудностей, которые испытывают учащиеся в понимании объектно-ориентированных концепций. И они были правы, создав это осязаемое учебное пособие, потому что определение, данное теми же авторами для объектов-соавторов, для новичка вроде меня почти как грязь: Мы называем соавторами объекты, которые будут отправлять или получать сообщения в курс выполнения обязанностей (Beck & Cunningham) .

Как в Launch School, так и в результатах поисковой системы был представлен ряд примеров объектов-соавторов, но, хотя конкретные примеры полезны, сами по себе они не обеспечивают всеобъемлющую структуру или ментальную модель, в которую можно поместить концепцию объектов-соавторов.

Итак, я немного покопался и задал вопросы в дискуссионном форуме Launch School 120, пытаясь прояснить характеристики объектов-соавторов. Я разбил свои выводы на три основных вопроса:

Что такое сотрудничество?

Сотрудничество - это способ моделирования отношений между различными объектами.

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

Наследование можно рассматривать как отношение is-a. Например, словарь - это книга.
Связь можно рассматривать как отношение имеет-а. Например, в библиотеке есть книги, поэтому между объектами класса Library и объектами класса Book существует ассоциативная связь.

Забери: отношения сотрудничества - это отношения ассоциация - не по наследству. Сотрудничество - это отношения имеет, а не отношения is-a.

Что такое объекты-соавторы и как их обнаружить в природе?

Во-первых, объекты соавторов могут быть любого типа: объект настраиваемого класса, массив, хэш, строка, целое число и т. Д. Класс объекта действительно зависит от программы, которую вы разрабатываете.

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

Один из способов обнаружить их в коде - это когда объект присваивается переменной экземпляра другого объекта внутри определения класса. Как видно из Примера 1 ниже, объект Person joe имеет имя - объект String со значением «Bob» - как часть своего состояния. Итак, объект "Bob", назначенный переменной экземпляра @name, является объектом-соавтором joe.

Пример 1:

class Person
  attr_reader :name
  def initialize(name)
    @name = name
  end
end
joe = Person.new("Bob")
p joe               # => #<Person:0x00000001f86c80 @name="Bob">
joe.name            # => "Bob"

Однако не всегда создание объекта-сотрудника происходит в самом определении. Иногда определение класса может просто определять установщик или другой метод экземпляра, но объект-участник не становится частью состояния основного объекта до тех пор, пока метод установки или экземпляра не будет вызван в другом месте, за пределами определения класса.

См. Другой способ обнаружить соавтора в коде в примере 2. В этом примере вы можете видеть, что объект Book book_1 не добавляется к состоянию my_library до тех пор, пока метод Library#add_book не будет вызван на my_library. Примечание. Из этого примера также видно, что book_1 имеет заголовок; @title - это String объектный сотрудник, объединивший объекты класса Book, который явно указан в методе Book#initialize.

Пример 2:

class Library
  def initialize
    @books = []
  end
  def add_book(book)
    @books << book
  end
end
class Book
  def initialize(title)
    @title = title
  end
end
my_library = Library.new
p my_library    # => #<Library:0x00000000c76050 @books=[]>
book_1 = Book.new('The Grapes of Wrath')
my_library.add_book(book_1)
p my_library    # => #<Library:0x00000001cedff0 @books=[#<Book:0x00000001cede10 @title="The Grapes of Wrath">]>

Убрать: объект соавтора является частью состояния другого объекта и может быть объектом любого класса. Тип объекта зависит от контекста вашей программы.

Когда начинается сотрудничество?

Итак, как вы можете видеть из примера 2, кажется, что сотрудничество с реальным объектом, который занимает определенное место в памяти, не всегда происходит сразу после создания экземпляра вашего основного объекта. Объект Book не становится частью состояния my_library до тех пор, пока не будет вызван метод Library#add_book и не добавит book_1 к состоянию my_library. Однако отношения сотрудничества между Library и Book существуют в определении для класса Library. Карта CRC для класса Library может выглядеть примерно так:

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

Окончательная ментальная модель (пока)

Что касается реальных объектов в памяти, сотрудничество происходит, когда один объект добавляется к состоянию другого объекта (то есть, когда для объекта вызывается метод). Однако более полезная ментальная модель: отношения сотрудничества существуют в дизайне (или намерении) нашего кода.

Благодарность: я хотел бы поблагодарить Карла Лингия за его вклад в мое понимание объектов-соавторов и за пример кода библиотеки-книги. Я цитировал его несколько раз в этом посте.

Техническое примечание. Что касается примера 2, объект @books технически является Array. Однако массив - это всего лишь способ организовать и сохранить Book объекты, которые будут его заполнять, предоставляя нам ряд Array методов для взаимодействия с нашей коллекцией книг. С точки зрения дизайна нашей программы имеет значение взаимосвязь между Library и Books, а не взаимосвязь между Library и Array.