Maks
Случае каких то правок может быть такое что придется менять иерархию сильно
Maks
Мысль в том, что без наследования работать ни чуть не сложнее и не хуже.
Dmitry
Мысль в том, что без наследования работать ни чуть не сложнее и не хуже.
Не встречал на просторах интернета доклады с конференций или книги Егора Бугаенко? У него очень специфический взгляд на ООП.
Maks
Неа. Я знаю что ооп можно заменить другими механизмами)
Maks
Точнее именно наследование)
Dmitry
Неа. Я знаю что ооп можно заменить другими механизмами)
не... там другое. Чел утверждает что все мы не правильно пользуемся объектами.
Maks
Нет правильного и не правильного в программировании)
Null
Изучаем Golang. Урок 13. Работа с файлами и выполнение shell команд https://www.youtube.com/watch?v=XRhE0oF5J_Y @Golang_google
Таршиш
Мысль в том, что без наследования работать ни чуть не сложнее и не хуже.
Без наследования -- это пещерный век: тонны говнокода, сотни программеров, регулярно исправляющих баги, постоянные авралы, высокая текучка -- в общем, все "прелести" лихих девяностых. Ну и редкий проект без ООП доживает до промышленного использования.
Olga
select { case update := <-upd: ChatID := update.Message.Chat.ID phone = update.Message.Text
Olga
точнее ChatID := update.Message.Chat.ID тут
Olga
Покажите определение типа Message
// инициализируем канал, куда будут прилетать обновления от API var ucfg tgbotapi.UpdateConfig = tgbotapi.NewUpdate(0) ucfg.Timeout = 60 upd, _ := bot.GetUpdatesChan(ucfg) var arr []string var str string for { select { case update := <-upd: ChatID := update.Message.Chat.ID phone = update.Message.Text
Таршиш
Ты не прав)
Можешь оставаться при своем мнении. Пешеход всегда прав, пока жив. А жить без ООП долго не получится - вытолкнут
Denis
Можешь оставаться при своем мнении. Пешеход всегда прав, пока жив. А жить без ООП долго не получится - вытолкнут
А можешь обосновать что такого необходимого в наследовании и когда оно не может быть заменено композицией или в случае го ланга встраиванием типов
🔥
Без ооп или без наследования?
Он еще не определился)
🔥
И клаудфлейр к томуже)
Olga
А текст ошибки?
panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x748e6b] goroutine 1 [running]: main.main()
Таршиш
А можешь обосновать что такого необходимого в наследовании и когда оно не может быть заменено композицией или в случае го ланга встраиванием типов
ООП базируется на трех китах: Наследование, Полиморфизм и Инкапсуляция. Теоретически писать можно и без всего этого. Можно вообще весь код в один файл напихать. Можно именовать переменные непонятными именами типа fgswb3sg Но это будет нечитабельный код и никто, кроме автора, не сможет в нем разобраться. Существуют правила, ориентированные на то, чтобы код мог быть прочитан другими программистами и чтобы он был легко пончтным и легко редактируемым. ООП придумали именно с этой целью. Это я писал про элементарную вежливость кодописателя. Но есть и другие причины пользоваться ООП. Например, чтобы грамотно организовать кол и не хранить в одном файле уйму разнородных данных. Без использовпния ООП в коде начинают преобладать конмтрукции if-else в огромном количестве. Вот, например, у Вас есть 50 типов датчиков и Вы определяете нужный по номеру.... Как Вы будете перебирать их? Уже несколько десятелегтий существуют Design Pattetns (Шаблоны Проектировпния), о них должен знать каждый программист, про них спрашивают на собеседованиях и ссылки на определенные шаблоны как правило присутствуют в постановке задачи для программиста. Все известные шаблоны проектирования оперируют классами. Процесс коммандной разработки ПО тоже классоподобный: каждый программист в команде пишет свой класс, например. Таким образом, класс - это не только способ оформления кода: это еще и зона ответственности одного командного разработчика.
🔥
А то так не очень понятно) Понятно только то что ты обращаешься к нулю)
🔥
ООП базируется на трех китах: Наследование, Полиморфизм и Инкапсуляция. Теоретически писать можно и без всего этого. Можно вообще весь код в один файл напихать. Можно именовать переменные непонятными именами типа fgswb3sg Но это будет нечитабельный код и никто, кроме автора, не сможет в нем разобраться. Существуют правила, ориентированные на то, чтобы код мог быть прочитан другими программистами и чтобы он был легко пончтным и легко редактируемым. ООП придумали именно с этой целью. Это я писал про элементарную вежливость кодописателя. Но есть и другие причины пользоваться ООП. Например, чтобы грамотно организовать кол и не хранить в одном файле уйму разнородных данных. Без использовпния ООП в коде начинают преобладать конмтрукции if-else в огромном количестве. Вот, например, у Вас есть 50 типов датчиков и Вы определяете нужный по номеру.... Как Вы будете перебирать их? Уже несколько десятелегтий существуют Design Pattetns (Шаблоны Проектировпния), о них должен знать каждый программист, про них спрашивают на собеседованиях и ссылки на определенные шаблоны как правило присутствуют в постановке задачи для программиста. Все известные шаблоны проектирования оперируют классами. Процесс коммандной разработки ПО тоже классоподобный: каждый программист в команде пишет свой класс, например. Таким образом, класс - это не только способ оформления кода: это еще и зона ответственности одного командного разработчика.
Ок)
🔥
на этой ChatID := update.Message.Chat.ID | line 62
в отладчике update.Message.Chat чему равен?
Denis
ООП базируется на трех китах: Наследование, Полиморфизм и Инкапсуляция. Теоретически писать можно и без всего этого. Можно вообще весь код в один файл напихать. Можно именовать переменные непонятными именами типа fgswb3sg Но это будет нечитабельный код и никто, кроме автора, не сможет в нем разобраться. Существуют правила, ориентированные на то, чтобы код мог быть прочитан другими программистами и чтобы он был легко пончтным и легко редактируемым. ООП придумали именно с этой целью. Это я писал про элементарную вежливость кодописателя. Но есть и другие причины пользоваться ООП. Например, чтобы грамотно организовать кол и не хранить в одном файле уйму разнородных данных. Без использовпния ООП в коде начинают преобладать конмтрукции if-else в огромном количестве. Вот, например, у Вас есть 50 типов датчиков и Вы определяете нужный по номеру.... Как Вы будете перебирать их? Уже несколько десятелегтий существуют Design Pattetns (Шаблоны Проектировпния), о них должен знать каждый программист, про них спрашивают на собеседованиях и ссылки на определенные шаблоны как правило присутствуют в постановке задачи для программиста. Все известные шаблоны проектирования оперируют классами. Процесс коммандной разработки ПО тоже классоподобный: каждый программист в команде пишет свой класс, например. Таким образом, класс - это не только способ оформления кода: это еще и зона ответственности одного командного разработчика.
Я не понял необходимость наследования из твоего сообщения, чем оно лучше композиции/встраивания типов? Да писать можно без всего этого, но разве в го ланге нет объектов? Или нельзя разбить код по файлам? Может быть нельзя наследовать методы(встроить тип)? Можно. Го ланг ООП-язык. В го ланге есть объекты (это структуры с прикрепленными к ним методами), также есть наследование через встраивание типов (по сути это синтаксический сахар над композицией) Читаемость кода вещь очень субъективная, я уверен большинство скажет что композиция проще для понимания чем наследование Го позволяет хранить код в разных файлах. Но как связан ООП и код в одном файле мне не ясно. Разбиение по файлам не делает язык ООП как и хранение кода в одном файле. Задача про уйму датчиков может быть решена через интерфейс DatchickInterface { getId() }, нет необходимости создавать сущность AbstractDatchick {getId()} Про дизайн патерны мне известно, все они реализуемы в го ланге, и все принципы солида в го ланге можно соблюсти, т.к. это ООП язык. В нем есть классы. Класс в го ланге реализуется через (struct + пачку методов). Класс это набор свойств и методов. Класс сущность описывающая объект определенной предметной области, го ланг эту возможность дает.
Dmitry
я делаю так arr := make([]string, 3)
Попробуй так arr := make([]string, 0)
Maks
ООП базируется на трех китах: Наследование, Полиморфизм и Инкапсуляция. Теоретически писать можно и без всего этого. Можно вообще весь код в один файл напихать. Можно именовать переменные непонятными именами типа fgswb3sg Но это будет нечитабельный код и никто, кроме автора, не сможет в нем разобраться. Существуют правила, ориентированные на то, чтобы код мог быть прочитан другими программистами и чтобы он был легко пончтным и легко редактируемым. ООП придумали именно с этой целью. Это я писал про элементарную вежливость кодописателя. Но есть и другие причины пользоваться ООП. Например, чтобы грамотно организовать кол и не хранить в одном файле уйму разнородных данных. Без использовпния ООП в коде начинают преобладать конмтрукции if-else в огромном количестве. Вот, например, у Вас есть 50 типов датчиков и Вы определяете нужный по номеру.... Как Вы будете перебирать их? Уже несколько десятелегтий существуют Design Pattetns (Шаблоны Проектировпния), о них должен знать каждый программист, про них спрашивают на собеседованиях и ссылки на определенные шаблоны как правило присутствуют в постановке задачи для программиста. Все известные шаблоны проектирования оперируют классами. Процесс коммандной разработки ПО тоже классоподобный: каждый программист в команде пишет свой класс, например. Таким образом, класс - это не только способ оформления кода: это еще и зона ответственности одного командного разработчика.
го позволяет реализовать ООП. Пусть тут нет наследования, но наследование это не панацея и имеет свои недостатки. Такие как большая вложенность наследования, которую не удобно менять по итогу. Для чего нужно наследование? 2 вещи: Общие поля, общая реализация для каких то методов. Это вопрос разделения логики. Ведь даже в С++ и других языках ты будешь обращаться не к базовому классу а к интерфейсу типа IДатчик.
Maks
И код будет выглядеть прекрасно без иф елс
Maks
#дуровдобавьлайкивтелеграм
Denis
https://pastebin.com/5Zrtc3fm
судя по доке в боту, message может не быть // optional Message *Message json:"message" Проверь что message реально есть, вдруг это какой-то другой update если message есть проверь что есть chat
Таршиш
Вам же по-любому надо осуществлять выбор нужного контракта. Вамж придется хранить информацию обо всех контрактах в головном модуле. И если в будущем надо будет скорректировать данные одного конкретного типа датчика, Вам придется лезть в длиииннный файл и менять там вместо того, чтобы сделать все изменения в классе, посвященном нужному типу. Сошлитесь на какой-нибудь шаблон проектирования чтобы я понял Вашу идею.
Таршиш
Я не понял необходимость наследования из твоего сообщения, чем оно лучше композиции/встраивания типов? Да писать можно без всего этого, но разве в го ланге нет объектов? Или нельзя разбить код по файлам? Может быть нельзя наследовать методы(встроить тип)? Можно. Го ланг ООП-язык. В го ланге есть объекты (это структуры с прикрепленными к ним методами), также есть наследование через встраивание типов (по сути это синтаксический сахар над композицией) Читаемость кода вещь очень субъективная, я уверен большинство скажет что композиция проще для понимания чем наследование Го позволяет хранить код в разных файлах. Но как связан ООП и код в одном файле мне не ясно. Разбиение по файлам не делает язык ООП как и хранение кода в одном файле. Задача про уйму датчиков может быть решена через интерфейс DatchickInterface { getId() }, нет необходимости создавать сущность AbstractDatchick {getId()} Про дизайн патерны мне известно, все они реализуемы в го ланге, и все принципы солида в го ланге можно соблюсти, т.к. это ООП язык. В нем есть классы. Класс в го ланге реализуется через (struct + пачку методов). Класс это набор свойств и методов. Класс сущность описывающая объект определенной предметной области, го ланг эту возможность дает.
Можно, конечно использовать композицию, но недолго, потому что в ней нет наследования
Olga
спасибо. Что-то я тупанул
Maks
Вам же по-любому надо осуществлять выбор нужного контракта. Вамж придется хранить информацию обо всех контрактах в головном модуле. И если в будущем надо будет скорректировать данные одного конкретного типа датчика, Вам придется лезть в длиииннный файл и менять там вместо того, чтобы сделать все изменения в классе, посвященном нужному типу. Сошлитесь на какой-нибудь шаблон проектирования чтобы я понял Вашу идею.
Контракт это по сути интерфейс. Что в случае с C++ что в случае с GO будет какой то массив разных классов(объектов) которые нужно опросить. Делаешь массив(срез) интерфейсов(что совершенно логично) и опрашиваешь их. А этот массив уже заполняешь структурами, у которых реализован этот интерфейс по разному. Одна структура на один тип датчика.
Maks
в чем разница то будет?
Maks
каждая структура(датчик) реализует по своему общий интерфейс
Таршиш
го позволяет реализовать ООП. Пусть тут нет наследования, но наследование это не панацея и имеет свои недостатки. Такие как большая вложенность наследования, которую не удобно менять по итогу. Для чего нужно наследование? 2 вещи: Общие поля, общая реализация для каких то методов. Это вопрос разделения логики. Ведь даже в С++ и других языках ты будешь обращаться не к базовому классу а к интерфейсу типа IДатчик.
Вот пример из жизни: датчик был сделан в компании A. В момент покупки некий программист написал класс для работы с этим датчиком. Потом прошло много времени, программист давно уже сменил работу, и вот, Вам нужно добавить новый функционал, но Вам не хочется разбираться в дебях кода Вашего предлественника. Вы просто знаете, что ЭТО работает и не хотите вдаваться в подробности. Вы просто наследуетесь от этого класса -- и все! Все ранее написанные модули будут работать, надо только перекомпилять новые. В случае же композиции Вы вам придется: 1. разобраться в коде Вашего предлественника (документация к датчику, скорее всего, будет потеряна, -- это как пить дать! Поэтому у Вас уйдет уйма времени на разборки) 2. Дописать свой функционал 3. Перекомпилить все ранее написанные модули (возможно, у Вас будет звонить телефон и недовольные голоса будут обвинять Вас в том, что из-за Вас у них перестал компилиться проект!)
🔥
Такс, а кто нибудь знает как жетбраинс на 3 части поделить?)
Таршиш
Но тут Вам всё равно потребуется наследование: Автомобиль и Грузовик наследуются от Транспорт.
Таршиш
Но тут Вам всё равно потребуется наследование: Автомобиль и Грузовик наследуются от Транспорт.
...а также Вам придется тянуть всю инфу о типах транспорта в главный модуль
Maks
...а также Вам придется тянуть всю инфу о типах транспорта в главный модуль
не нужно тянуть ничего. Нужно реализовывать интерфейс.
Denis
Но тут Вам всё равно потребуется наследование: Автомобиль и Грузовик наследуются от Транспорт.
Так там же интерфейс, наследуются логистики, транспорты как раз реализации интерфейса
Maks
Даже в ООП при наследовании и всём прочем никогда не нужно использовать базовый класс где то
Maks
Только интерфейсы
Таршиш
зачем им наследоваться от транспорта?
чтобы в случае измения правил работы транспорта делать изменения в ОДНОМ , классе, а не во всех классах, которые его используют. Прикиньте: изменились тарифы и правила пользования дорогами: что, теперь в классе каждого типа транспорта делать изменения?
Denis
Вот пример из жизни: датчик был сделан в компании A. В момент покупки некий программист написал класс для работы с этим датчиком. Потом прошло много времени, программист давно уже сменил работу, и вот, Вам нужно добавить новый функционал, но Вам не хочется разбираться в дебях кода Вашего предлественника. Вы просто знаете, что ЭТО работает и не хотите вдаваться в подробности. Вы просто наследуетесь от этого класса -- и все! Все ранее написанные модули будут работать, надо только перекомпилять новые. В случае же композиции Вы вам придется: 1. разобраться в коде Вашего предлественника (документация к датчику, скорее всего, будет потеряна, -- это как пить дать! Поэтому у Вас уйдет уйма времени на разборки) 2. Дописать свой функционал 3. Перекомпилить все ранее написанные модули (возможно, у Вас будет звонить телефон и недовольные голоса будут обвинять Вас в том, что из-за Вас у них перестал компилиться проект!)
Сомневаюсь что наследоваться от этого класса не читая его реализацию можно. Вы ведь можете не только расширять, но и переопределить какой-то метод. В случае интерфейса, нужно просто написать реализацию. Разбираться также не придется, хотя я лукавлю, старую реализацию интерфейса вы все равно пробежите глазами, чтобы знать че там вообще примерно должно быть. Также в коде интерфейса разобраться проще, чем в коде абстрактного класса, т.к. в интерфейсе не будет реализация общих методов Также может быть так, что ДатчикА наследует АбстрактныйДатчик. Но новый датчик произвела компанияБ и там совершенно другая реализация работы с датчиком и сову на глобус нельзя натянуть. Потому не получится сделать наследование от АбстрактногоДатчика, т.к. код не совместим с ДатчикБ. В таком случае придется долго и упорно рефакторить, если АбстракныйДатчик уже успел пустить корни по проекту. В случае с интерфейсом должно быть по проще. Достаточно будет сделать новую реализацию. В случае абстрактного класса возможно придется переопределить пару методов. В вашем примере с фабричным методом(для примера render) может оказаться что в родителе логика не просто return render(), а какая нибудь if(isRevert) { return render()}else{ return revert(render()) } не заглянув в реализацию немозможно будет гарантировать что реализация метода render в ребенке будет коректно работать в родителе и рабоать так как вы ожидали.
Maks
это методы Транспорта.
как тариф относится к транспорту? В случае композиции у тебя будет класс реализующий эти методы, который будет вкладываться в разные объекты например как вы сказали грузовик и машина и там будет так же отрабатывать. Супер утрированно.
Таршиш
Сомневаюсь что наследоваться от этого класса не читая его реализацию можно. Вы ведь можете не только расширять, но и переопределить какой-то метод. В случае интерфейса, нужно просто написать реализацию. Разбираться также не придется, хотя я лукавлю, старую реализацию интерфейса вы все равно пробежите глазами, чтобы знать че там вообще примерно должно быть. Также в коде интерфейса разобраться проще, чем в коде абстрактного класса, т.к. в интерфейсе не будет реализация общих методов Также может быть так, что ДатчикА наследует АбстрактныйДатчик. Но новый датчик произвела компанияБ и там совершенно другая реализация работы с датчиком и сову на глобус нельзя натянуть. Потому не получится сделать наследование от АбстрактногоДатчика, т.к. код не совместим с ДатчикБ. В таком случае придется долго и упорно рефакторить, если АбстракныйДатчик уже успел пустить корни по проекту. В случае с интерфейсом должно быть по проще. Достаточно будет сделать новую реализацию. В случае абстрактного класса возможно придется переопределить пару методов. В вашем примере с фабричным методом(для примера render) может оказаться что в родителе логика не просто return render(), а какая нибудь if(isRevert) { return render()}else{ return revert(render()) } не заглянув в реализацию немозможно будет гарантировать что реализация метода render в ребенке будет коректно работать в родителе и рабоать так как вы ожидали.
а зачем мне проглядывать глазами старую реализацию?
Dmitry
Maks
Проф деформация когда ты работаешь всю жизнь на одном языке и не знаешь как двигается мир.
Maks
Я работал на 3х языках и когда то тоже думал как жить без наследования и ооп
Maks
потом понял что это всё постная херня
Таршиш
потом понял что это всё постная херня
Вы, наверное, никогда в команде не работали
Таршиш
Я не говорил, про то, чтт тарифы надо пихать. Но логика, обслуживабщая тарифную информацию должна быть у транспорта. А тарифы, конечно пускай хранятся в отдельном модуле или в ДБ -- с этим я не спорю. Принцип успешного программирования должен быть таким, чтобы любое изменение задачи в будущем приводило к изменеию только в одном классе. Примерно так. То есть ООП помогает избавляться от избыточного кода
Denis
Я не говорил, про то, чтт тарифы надо пихать. Но логика, обслуживабщая тарифную информацию должна быть у транспорта. А тарифы, конечно пускай хранятся в отдельном модуле или в ДБ -- с этим я не спорю. Принцип успешного программирования должен быть таким, чтобы любое изменение задачи в будущем приводило к изменеию только в одном классе. Примерно так. То есть ООП помогает избавляться от избыточного кода
А если произойдет подорожание всех видов транспорта на 10%, придется менять 40 классов например? А если есть какой-то ТарифКалькулятор {расчитатьДляТранспорта(ИнтерфейсТранспорта)} Тогда придется менять только калькулятор. А транспорт будет только доставлять, но цены считать не будет. Как и в реальной жизни, грузчик может не знать сколько стоит погрузка, он кидает мешки, а оплатой занимается офис
Таршиш
Вот, например, гипотетический случай: МинТранс издал приказ, в соответствии с котором изменился порядок следования машин через определенные зоны, например в зависимости от типа используемого двигателя и еще чего-либо. Ваша задача: сделать измене6ия в коде так, чтобы: 1. любой программист мог понять причину почему это сделано 2. На случай, если МинТранс издаст дополнения к новому закону, Вам надо будет сделать изменения только в ОДНОМ месте
Denis
чтобы в случае измения правил работы транспорта делать изменения в ОДНОМ , классе, а не во всех классах, которые его используют. Прикиньте: изменились тарифы и правила пользования дорогами: что, теперь в классе каждого типа транспорта делать изменения?
А вы можете гарантировать что изменения в базовом классе не нарушат логику работы наследников? Вдруг какие-то методы переопределены. Вдруг там появились дополнительные условия? Хотя в случае композиции придется также все проверять и читать (с помощью IDE, но тем не менее) Если рассматривать композицию и наследование как способ расшаривания общего кода, при условии что оба варианта при этом реализуют как-то интерфейс(IDatchik/ITransport например) то разницы почти никакой нет. Но при этом композиция сильнее инкапсулирует логику родителя от логики наследника. При композиции зависимость может быть от интерфейса вообще(больше абстрактности), при наследовании от базового класса(меньше абстрактности) Но композиция должна быть не такой: Датчик(ИндификаторДатчика). А то это как в Собаку запихивать НастройкиСобаки А скорее такой ЛокаторДатчиков([]Датчиков) и локатор может вернуть тебе id датчика или найти датчик по id например. Если у тебя не id датчика, а например какой-нибудь номер порта, то тогда такая организация будет более логичной. Т.к. Локатор будет маршрутизировать обработку данных с физических датчиков, отрывать порты, закрывать и т.п. А сам класс Датчика сможет обрабатывать сырые данные например.
Denis
Вот, например, гипотетический случай: МинТранс издал приказ, в соответствии с котором изменился порядок следования машин через определенные зоны, например в зависимости от типа используемого двигателя и еще чего-либо. Ваша задача: сделать измене6ия в коде так, чтобы: 1. любой программист мог понять причину почему это сделано 2. На случай, если МинТранс издаст дополнения к новому закону, Вам надо будет сделать изменения только в ОДНОМ месте
Должен быть класс ПостроительМаршрутов{построить(Транспорт)} Транспорт должен принять груз и провести его по маршруту. Если МинТранс нам закрутил гайки или мы вдруг увидели что на улицах пробки, то построитель машрутов нам даст всегда нужный маршрут А транспорт может быть так реализовани Транспорт { принятьГруз() доставитьПоМаршруту(маршрут) }
Denis
Транспорт уже куплен. Подорожание пофиг. Но Вы ведь все равно тарифы из БД брать будете
Это требование бизнеса, владелец компании захотел больше денег, инфляция, все дела, конкуренты на рынке пропали, можно грести больше бабла
Denis
Вот, например, гипотетический случай: МинТранс издал приказ, в соответствии с котором изменился порядок следования машин через определенные зоны, например в зависимости от типа используемого двигателя и еще чего-либо. Ваша задача: сделать измене6ия в коде так, чтобы: 1. любой программист мог понять причину почему это сделано 2. На случай, если МинТранс издаст дополнения к новому закону, Вам надо будет сделать изменения только в ОДНОМ месте
Если же мы хотим чтобы транспорт сам строил маршрут, то можно ему передать маршрутизатор как зависимость, через конструктор, как в машине есть навигатор, это отдельный девайс, так же и тут. Отдельный класс для навигации. При чем такая схема может быть более предпочтительной если мы строим маршруты например по воде/воздуху/дороге, тогда конкретные реализации транспортов будут зависить от конкретных реализаций навигаторов (через композицию)
Таршиш
А вы можете гарантировать что изменения в базовом классе не нарушат логику работы наследников? Вдруг какие-то методы переопределены. Вдруг там появились дополнительные условия? Хотя в случае композиции придется также все проверять и читать (с помощью IDE, но тем не менее) Если рассматривать композицию и наследование как способ расшаривания общего кода, при условии что оба варианта при этом реализуют как-то интерфейс(IDatchik/ITransport например) то разницы почти никакой нет. Но при этом композиция сильнее инкапсулирует логику родителя от логики наследника. При композиции зависимость может быть от интерфейса вообще(больше абстрактности), при наследовании от базового класса(меньше абстрактности) Но композиция должна быть не такой: Датчик(ИндификаторДатчика). А то это как в Собаку запихивать НастройкиСобаки А скорее такой ЛокаторДатчиков([]Датчиков) и локатор может вернуть тебе id датчика или найти датчик по id например. Если у тебя не id датчика, а например какой-нибудь номер порта, то тогда такая организация будет более логичной. Т.к. Локатор будет маршрутизировать обработку данных с физических датчиков, отрывать порты, закрывать и т.п. А сам класс Датчика сможет обрабатывать сырые данные например.
То, что базовые методы не будут переопределены (или, скажем так: будут переопределены КОРОЕКТНО) можно гарантировать введя ответственность программиста за КЛАСС. То есть каждый класс -- это зона ответственности того или иного разработчика. Всегда легко понять, кто накосячил. Ну и есть другие плюсы этого плдхода, о которых я не пишу тут. Практика показывает, что коллективная ответственность -- это зло, приводящее к говнокоду (исключение составляют только некоторые экстремальные методики управления процессом разработки типа agile и иже с ним, но в этом случае пролема решается совсем другими методами). А в Вашем случае, один и тот же модуль будет редактироваться РАЗНЫМИ программистами и в случае возникновения проблем они будут спихивать ответственность друг на дружку
Maks
То, что базовые методы не будут переопределены (или, скажем так: будут переопределены КОРОЕКТНО) можно гарантировать введя ответственность программиста за КЛАСС. То есть каждый класс -- это зона ответственности того или иного разработчика. Всегда легко понять, кто накосячил. Ну и есть другие плюсы этого плдхода, о которых я не пишу тут. Практика показывает, что коллективная ответственность -- это зло, приводящее к говнокоду (исключение составляют только некоторые экстремальные методики управления процессом разработки типа agile и иже с ним, но в этом случае пролема решается совсем другими методами). А в Вашем случае, один и тот же модуль будет редактироваться РАЗНЫМИ программистами и в случае возникновения проблем они будут спихивать ответственность друг на дружку
А если программист который написал говнокод в классе ушел и спустя много лет пришел новый?
Таршиш
А если программист который написал говнокод в классе ушел и спустя много лет пришел новый?
Если использовался метод персональной ответственности, то говнокода не было. Такое бывает только при коллективной ответственности