Re[2]: Интерфейсы против функций
От: varenikAA  
Дата: 09.11.20 05:26
Оценка:
Здравствуйте, yenik, Вы писали:

AA>>Достаточно набора функций,


Y>А если набор функций — это 10 функций? Не легче ли инжектировать 1 интерфейс?


Уверены что в одном методе нужно 10 функций?
Возможно следует использовать композицию для получения из 10-ти 1-й функции.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Интерфейсы против функций
От: varenikAA  
Дата: 09.11.20 06:22
Оценка:
Здравствуйте, yenik, Вы писали:

Y>Определяй интерфейс в той же сборке, и не потянет.

Это если есть доступ к исходному коду.

Y>Не факт. Если заменить myTypeInstance.DoThings() на doThings(myTypeInstance), тогда то на то и выходит.


не совсем, все же в этом случае зависимость односторонняя. в первом случае зависимость в обе стороны.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Интерфейсы против функций
От: yenik  
Дата: 09.11.20 10:12
Оценка:
AA>
AA>public Notificator(IEmailSender sender)
AA>


AA>>>Достаточно набора функций,


Y>>А если набор функций — это 10 функций? Не легче ли инжектировать 1 интерфейс?


AA>Уверены что в одном методе нужно 10 функций?


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

AA>Возможно следует использовать композицию для получения из 10-ти 1-й функции.


Также возможно, что эти функции нужны по отдельности.
Re[5]: Интерфейсы против функций
От: yenik  
Дата: 10.11.20 08:17
Оценка:
Y>>Определяй интерфейс в той же сборке, и не потянет.
AA>Это если есть доступ к исходному коду.

Y>>Не факт. Если заменить myTypeInstance.DoThings() на doThings(myTypeInstance), тогда то на то и выходит.


AA>не совсем, все же в этом случае зависимость односторонняя. в первом случае зависимость в обе стороны.


Не понял эту мысль. Одна сборка зависит от другой. Почему в обе стороны?
Re[3]: Интерфейсы против функций
От: yenik  
Дата: 10.11.20 08:44
Оценка:
AA>>>Достаточно набора функций,

Y>>А если набор функций — это 10 функций? Не легче ли инжектировать 1 интерфейс?


S>Интерфейс нужно реализовать, что бы его инжектировать. А 10 функций можно взять готовых или скомбинировать их неким образом.

S>Более того, 10 функций можно заменить структурой с 10ю полями и в отношении количества инжектируемых функций такая структура будет ничем не хуже 1-го интерфейса. А в некотором отношении даже лучше, т.к. структуры не нужно реализовывать, достаточно лишь инициировать члены.

Да, структура — это получше, чем 10 параметров. Но в итоге получается некое квази-ООП в стиле C с указателями на функции, в котором отсутствуют возможности ООП в стиле C++. От этого в своё время ушли, и прогрессивность такого подхода неочевидна. Хотя в каких-то случаях он может быть вполне уместен.
Необходимость реализовывать интерфейс, как всякое техническое решение, имеет плюсы и минусы. Плюс в том, что код сгруппирован, его легче поддерживать.

А вообще было бы прикольно, если бы C# позволял такие вещи:
interface IFoo
{
    string GetA();
}

var a = "%$#@$%#%^";
var bar = new<IFoo>
{
    GetA = () => { return a; }    
}
Re[4]: Интерфейсы против функций
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.11.20 09:08
Оценка:
Здравствуйте, yenik, Вы писали:

AA>>>>Достаточно набора функций,


Y>>>А если набор функций — это 10 функций? Не легче ли инжектировать 1 интерфейс?


S>>Интерфейс нужно реализовать, что бы его инжектировать. А 10 функций можно взять готовых или скомбинировать их неким образом.

S>>Более того, 10 функций можно заменить структурой с 10ю полями и в отношении количества инжектируемых функций такая структура будет ничем не хуже 1-го интерфейса. А в некотором отношении даже лучше, т.к. структуры не нужно реализовывать, достаточно лишь инициировать члены.

Y>Да, структура — это получше, чем 10 параметров. Но в итоге получается некое квази-ООП в стиле C с указателями на функции, в котором отсутствуют возможности ООП в стиле C++. От этого в своё время ушли, и прогрессивность такого подхода неочевидна. Хотя в каких-то случаях он может быть вполне уместен.


Уместно это там, кде кучка функций не связана общим состоянием, как это в ООП. Т.е. мы не интерфейс изменяемого контейнера распилили и передаем эти функции отдельно, сгруппировав их в структуру. В таком случае преимущества над интерфейсом нет.

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

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


Y>А вообще было бы прикольно, если бы C# позволял такие вещи:

Y>
Y>interface IFoo
Y>{
Y>    string GetA();
Y>}

Y>var a = "%$#@$%#%^";
Y>var bar = new<IFoo>
Y>{
Y>    GetA = () => { return a; }    
Y>}
Y>


В F# это называется Object expression
Re[4]: Интерфейсы против функций
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 10.11.20 18:28
Оценка:
Здравствуйте, gyraboo, Вы писали:

G> Задачи типа многопоточности и распределённости не беру, т.к. тут всё понятно, ФП в этом изначально сильна.


Это миф, кстати. Многие ФЯзыки или до сих пор не умеют в многоядерность, или много лет не умели. У многих самая популярная структура данных — односвязный список, работу с которым параллелить довольно сложно. У флагмана ФП Хаскеля есть умение во многоядерность и есть разнообразие структур данных, но сборщик мусора ставит все потоки на паузу, порой надолго.
Re[4]: Интерфейсы против функций
От: varenikAA  
Дата: 11.11.20 03:28
Оценка:
Здравствуйте, yenik, Вы писали:

Y>А вообще было бы прикольно, если бы C# позволял такие вещи:

Y>
Y>var bar = new<IFoo>
Y>{
Y>    GetA = () => { return a; }    
Y>}
Y>


Внезапно, в олдскул:

        btn.setOnAction(new EventHandler<ActionEvent>() {
 
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });


И, да, это было невероятно удобно!
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: Интерфейсы против функций
От: varenikAA  
Дата: 11.11.20 03:31
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>Это миф, кстати. Многие ФЯзыки или до сих пор не умеют в многоядерность, или много лет не умели. У многих самая популярная структура данных — односвязный список, работу с которым параллелить довольно сложно. У флагмана ФП Хаскеля есть умение во многоядерность и есть разнообразие структур данных, но сборщик мусора ставит все потоки на паузу, порой надолго.


Разве там не регулируется кол-во потоков как в ГО (1 поток на ядро)? В этом случае, как подсказывает интуиция, не должно быть проблем со сборкой мусора. если только сборщик не наткнулся на циклические ссылки. т.е. это возможно со сборщиком что-то не так.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: Интерфейсы против функций
От: · Великобритания  
Дата: 11.11.20 09:20
Оценка: 2 (1)
Здравствуйте, yenik, Вы писали:

y> А вообще было бы прикольно, если бы C# позволял такие вещи:

java позволяет:
interface IFoo
{
    String getA();
}

IFoo a = () -> "$#@$%#%^";

Но это, ясен пень, только для интерфейсов с одним методом.
avalon/2.0.6
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Интерфейсы против функций
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 11.11.20 12:53
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Разве там не регулируется кол-во потоков как в ГО (1 поток на ядро)?


В Хаскеле есть и зеленые потоки, вроде горутин, и обычные системные. Наверняка регулируется. Но толку-то, если сборщику нужно старое поколение собирать, он все равно все остановит, ибо старое поколение кучи общее для всех потоков, а чистить параллельно, как в свежих версиях Го, он пока не умеет, вроде.
Re[5]: Интерфейсы против функций
От: ути-пути Россия  
Дата: 13.11.20 07:42
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>1) ООП вынуждает привязывать методы к данным, хотя чаще всего в домене эта связь отсутствует. В результате, эта связь делается случайным образом, что приводит к каше в коде. Например, можно написать код в стиле ООП: "Холст.НарисуйКартину(кисть)", либо "Кисть.НарисуйКартину(холст)". Какой из этих двух вариантов правильный? Тут нет неправильного варианта. Реализован будет произвольный из них, смотря какая пятка зачесалась у программиста. Хотя в ФП стиле все однозначно: "НарисуйКартину(холст, кисть)". Нет никаких разночтений.


T>2) Данные жёстко связаны с методами. Какой бы из описанных в предыдущем пункте мы не выбрали вариант, мы будем жёстко связаны принятым случайным образом решением. Если мы выбираем вариант

"Холст.НарисуйКартину(кисть)", то НарисуйКартину жёстко привязана к холсту и мы сможем в дальнейшем рисовать картины исключительно только на холстах. В другом варианте мы будем жёстко привязаны к кисти и сможем рисовать только кистью. С другой стороны, при ФП декомпозиции, функция НарисуйКартину(где, чем) ни к чему не привязана и может рисовать на чём угодно и чем угодно, если это пригодно для рисования.

T>3) ООП провоцирует на создание большого количества лишних сущностей. Для борьбы с предыдущими проблемами приходится вводить большое количество искусственных сущностей, которые отсутствуют в исходном домене. Для этих сущностей часто даже невозможно придумать адекватного названия, вот и появляются всякие FooManager, BarHelper, все это обмазывается толстым слоем абстрактных фабрик, визиторов, репозиториев и прочих паттернов, которые для эксперта из доменной области звучат, как тарабарщина и мешают тем самым применению DDD. В результате программист вместо решения задачи из предметной области воюет с визиторами и декораторами.


Какие-то жабные стереотипы. Большинство языков на это не повелись, и в них все это легко и непринужденно решается свободными функциями. Да и в жабе это возможно, если рассматривать часть классов лишь как пространства имен.
Ничто не мешает на плюсах написать "НарисуйКартину(холст, кисть)", а ведь только на этом все эти претензии строятся
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[5]: Интерфейсы против функций
От: · Великобритания  
Дата: 13.11.20 11:11
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T> На мой взгляд, если исключить неадекватов, лепящих монады и теории категорий во все дыры, то значительно проще.


T> 1) ООП вынуждает привязывать методы к данным, хотя чаще всего в домене эта связь отсутствует. В результате, эта связь делается случайным образом, что приводит к каше в коде. Например, можно написать код в стиле ООП: "Холст.НарисуйКартину(кисть)", либо "Кисть.НарисуйКартину(холст)". Какой из этих двух вариантов правильный? Тут нет неправильного варианта. Реализован будет произвольный из них, смотря какая пятка зачесалась у программиста. Хотя в ФП стиле все однозначно: "НарисуйКартину(холст, кисть)". Нет никаких разночтений.

Хрень какая-то. Выбор в данном случае будет основан на том кому нужен доступ к приватным членам и диспатчу по динамическому типу (т.е. виртуальный метод). Т.е. как раз те дыры, что пытаются заткнуть монадами и теориями категорий в ФП.
Иначе будет просто статическая функция как в ФП.

T> 2) Данные жёстко связаны с методами. Какой бы из описанных в предыдущем пункте мы не выбрали вариант, мы будем жёстко связаны принятым случайным образом решением.

Если не надо — не связывай, не будут. И решения случайные лучше не принимать. Да и не проблема это вовсе, есть рефакторинг, часто автоматический.

T> 3) ООП провоцирует на создание большого количества лишних сущностей. Для борьбы с предыдущими проблемами приходится вводить большое количество искусственных сущностей, которые отсутствуют в исходном домене. Для этих сущностей часто даже невозможно придумать адекватного названия, вот и появляются всякие FooManager, BarHelper, все это обмазывается толстым слоем абстрактных фабрик, визиторов, репозиториев и прочих паттернов, которые для эксперта из доменной области звучат, как тарабарщина и мешают тем самым применению DDD. В результате программист вместо решения задачи из предметной области воюет с визиторами и декораторами.

Паттерны в ФП тоже есть в достатке, просто они другие.

T> В результате, ФП проект со временем менее подвержен превращением в кашу. В фп стиле легче писать правильно и труднее говнокодить.

По-моему уже давно договорились, что оптимум: ООП на глобальном уровне дизайна, ФП — локально на уровне реализации тела методов.
avalon/2.0.6
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Интерфейсы против функций
От: samius Япония http://sams-tricks.blogspot.com
Дата: 13.11.20 17:47
Оценка:
Здравствуйте, gyraboo, Вы писали:

G>Здравствуйте, varenikAA, Вы писали:


AA>>Получается, что функции высшего порядка делают код чище и проще, и интерфейсы тут как бы не особо уже нужны.


G>Я вот тоже последнее время задаюсь вопросом, что если функциональное программирование лучше (в частности, для написания распределенных и многопоточных задач), то как в нём реализовать SOLID, GRASP, ООП-паттерны и прочие достижения ООП. Или же есть какая-то замена этим подходам, если да, то какая? В плане написания полноценного бизнес-приложения, как это делается например на Java/Spring. Пока что те книги, что я читал по ФП, полной картины не дают, и в своей работе ФП я пока применяю эпизодически, внутри классических ООП-обёрток и архитектуры, построенной по принципам SOLID и Ко. Возможно, в мире ФП пока эти принципы не выкристаллизовались ещё, или я просто не знаю где искать?


Подвернулась презентация. Сам не смотрел, но думаю, что там тема раскрыта. На сайте Влашина я давно пасусь.
https://vimeo.com/113588389
Re[5]: Интерфейсы против функций
От: DenisCh Россия  
Дата: 14.11.20 02:08
Оценка:
Здравствуйте, mrTwister, Вы писали:

T>1) ООП вынуждает привязывать методы к данным, хотя чаще всего в домене эта связь отсутствует. В результате, эта связь делается случайным образом, что приводит к каше в коде. Например, можно написать код в стиле ООП: "Холст.НарисуйКартину(кисть)", либо "Кисть.НарисуйКартину(холст)". Какой из этих двух вариантов правильный? Тут нет неправильного варианта. Реализован будет произвольный из них, смотря какая пятка зачесалась у программиста. Хотя в ФП стиле все однозначно: "НарисуйКартину(холст, кисть)". Нет никаких разночтений.


А если сделать Картина.Нарисовать(где, чем)?
Тогда, как и в твоём примере мы будем жёстко привзавны. Но теперь к картине. То есть мы не сможем на холсте нарисовать не картину, а, например, рисунок
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[6]: Интерфейсы против функций
От: mrTwister Россия  
Дата: 14.11.20 07:06
Оценка:
Здравствуйте, ути-пути, Вы писали:

УП>Какие-то жабные стереотипы.


Не жабные, а ООПэшные. Да, ООП можно не использовать.
лэт ми спик фром май харт
Re[6]: Интерфейсы против функций
От: mrTwister Россия  
Дата: 14.11.20 07:25
Оценка:
Здравствуйте, ·, Вы писали:


·>Хрень какая-то. Выбор в данном случае будет основан на том кому нужен доступ к приватным членам и диспатчу по динамическому типу (т.е. виртуальный метод). Т.е. как раз те дыры, что пытаются заткнуть монадами и теориями категорий в ФП.

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

По поводу диспатча — диспатч нужен не типу, а конкретному алгоритму, этот тип использующему. Но при этом задается диспатч в типе. То есть при проектировании типа нам надо иметь ввиду конкретный алгоритм. И если алгоритм немного меняется, либо надо написать немного другой алгоритм, то внезапно может выяснится, что диспатч надо делать иначе и наш старый код вместо переиспользования обрастает костылями, декораторами, адаптерами и стратегиями
лэт ми спик фром май харт
Re[6]: Интерфейсы против функций
От: mrTwister Россия  
Дата: 14.11.20 07:29
Оценка:
Здравствуйте, DenisCh, Вы писали:

DC>А если сделать Картина.Нарисовать(где, чем)?

DC>Тогда, как и в твоём примере мы будем жёстко привзавны. Но теперь к картине. То есть мы не сможем на холсте нарисовать не картину, а, например, рисунок

Только это будет не картина (картина получается в результате работы метода), а скорее функция рисования картины, которая на вход получает данные. Вот мы и пришли к функциональному программированию, когда есть функция и данные для нее, только в нагрузку получили еще кучу синтаксического оверхеда (тм) от ООП, когда вместо того, чтобы просто написать функцию мы пишем класс-функцию.
лэт ми спик фром май харт
Re[7]: Интерфейсы против функций
От: ути-пути Россия  
Дата: 14.11.20 11:42
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T>Не жабные, а ООПэшные. Да, ООП можно не использовать.


Так ООП, ФП и т.п. — это сферовакуум, а в реальном мире есть вполне конкретные ЯП. И они часто поддерживают много парадигм как раз потому, что нет весомого повода загонять разработчика в какую-то одну.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[7]: Интерфейсы против функций
От: · Великобритания  
Дата: 14.11.20 15:34
Оценка: +1
Здравствуйте, mrTwister, Вы писали:

T> ·>Хрень какая-то. Выбор в данном случае будет основан на том кому нужен доступ к приватным членам и диспатчу по динамическому типу (т.е. виртуальный метод). Т.е. как раз те дыры, что пытаются заткнуть монадами и теориями категорий в ФП.

T> Приватные данные есть не сами по себе, а появляются для конкретной реализации, и появляются они в том месте, где происходит реализация. То есть не приватные данные определяют реализацию, а наоборот.
Это проблема курицы и яйца. Какая разница кто кого определяет?
Простой пример. Пусть у нас будет тип Стек. Его можно реализовать разными способами. Например, в виде списка и в виде массива. Приватными данными будут разные вещи. Например, указатель на голову и счётчик размера в первом случае; или массив и индекс в нём во втором случае.
Вот тут и диспатч, тут и приватные данные. Как это делать в ФП без монад и паттернов — неясно.

T> По поводу диспатча — диспатч нужен не типу, а конкретному алгоритму, этот тип использующему. Но при этом задается диспатч в типе. То есть при проектировании типа нам надо иметь ввиду конкретный алгоритм. И если алгоритм немного меняется, либо надо написать немного другой алгоритм, то внезапно может выяснится, что диспатч надо делать иначе и наш старый код вместо переиспользования обрастает костылями, декораторами, адаптерами и стратегиями

Или код рефакторится и пишется немного другой алгоритм... Ты как-то демонизируешь ООП.
Костылей в ФП тоже вагон и маленькая тележка.
Костыли это результат определённого процесса разработки, а не стиля программирования.
avalon/2.0.6
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.