PDA

Просмотр полной версии : использовать или не использовать интерфейсы


passertm
09.01.2011, 02:28
Заметил за собою, что во Флеше, уже который раз предпочитаю использовать возможность передачи функции, нежели создание интерфейса (хотя в других языках, где невозможно передавать функции как параметр, достаточно юзаю интерфейсы).
Например класс Х работает с другими классами у которых есть функция DoSomeThing. Можно

public interface iprocessor {
function DoSomeThing(par:int):void;
}
public class X {
function setProcessor(o:iprocessor){
....
}
}

т.е. как в других языках.
А можно

public class X {
function setProcessor(f:Function){
....
}
}


Так вот, второй метод проще. Как минимум не приходится создавать лишний файл (интерфейса) и не приходится навязывать классу имя метода (соответственно он не может конфликтовать с другим интерфейсом). Поэтому, если функций до трех (включительно), то я (точнее душа моя) предпочитаю обходится без интерфейса. А как вы делаете? И в чем преимущества такого решения (допускаются даже субъективные варианты типа "при дебаге удобнее").

wvxvw
09.01.2011, 10:49
Передаю то, что нужно для задачи. К функциям пишу комментарий типа: addChild->DisplayObject->DisplayObject.

alatar
09.01.2011, 11:42
Зависит от задачи. Если предполагается, что нужна функция (например, какая-нибудь filterFunction), то передается функция. Если предполагается работа именно с классом, то интерфейс. У того же процессора, помимо DoSomeThing могут быть и параметры, которые необходимо настроить.

passertm
09.01.2011, 13:07
Ответы расплывчаты. Я так понимаю вы тоже как я использууете.
Вот к примеру для Undo что я делаю. Все классы в которых можно сделать Undo должны иметь функции undo и redo.
Какое решение бы вы использовали.
интерфейс или две функции??

iNils
09.01.2011, 13:12
Можно и наследование использовать. Если нет возможности, то интерфейс.

alatar
09.01.2011, 13:14
Вопросы не менее расплывчаты. Какое отношение некие классы имеют к undo/redo? Я бы реализовал undo/redo командами, и они бы имели интерфейс.

dimarik
10.01.2011, 00:04
Заметил за собою, что во Флеше, уже который раз предпочитаю использовать возможность передачи функции, нежели создание интерфейса

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

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

expl
10.01.2011, 00:54
Так вот, второй метод проще
Второй метод не только проще, но и гибше (если передаваемые в какой-то метод функции не должны быть связаны между собой). Да и инкапсуляция лучше - нет непобходимости делать передаваемые функции публичными.

Только беда в том, что на дворе 2011 год, а в actionScript3 до сих пор параметры функций не типизируются во время компиляции (в haXe это было и есть даже для flashplayer8), как, врочем и генериков до сих пор нет :(

А вспомнить какие параметры надо передавать в этот колбек и надо ли - очень тяжело.
Поэтому предпочитаю использовать интерфейсы во всех случаях, при которых это не приводит к нагромождению кода и другим проблемам (а часто приводит)

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

surlac
10.01.2011, 00:58
Можно и наследование использовать. Если нет возможности, то интерфейс.
Извините, не согласен. Насколько я знаю, должно быть как раз наоборот. Не буду долго объяснять, просто процитирую труд Гаммы, Хелма и других товарищей из Gang Of Four "Design Patterns:Elements of Reusable Object-Oriented Software":
предпочитайте композицию наследованию класса
Думаю, если учесть принципиальную разницу наследования и композиции (интерфейс) - статическое и динамическое связывание (соответственно) - все становится ясно. Наследование легче воспринимается программером, т.к. структура постоянна во время выполнения программы, композиция же сложнее воспринимается, но эффективнее.

если функций до трех (включительно), то я (точнее душа моя) предпочитаю обходится без интерфейса. А как вы делаете?
Тут тоже процитирую GoF:
принцип объектно-ориентированного проектирования для повторного использования: программи-
руйте в соответствии с интерфейсом, а не с реализацией.

expl
10.01.2011, 01:10
Тут тоже процитирую GoF:
принцип объектно-ориентированного проектирования для повторного использования: программи-
руйте в соответствии с интерфейсом, а не с реализацией.
ИМХО это высказывание не в тему.

Передавая классу функцию Вы завязываете этот класс на СИГНАТУРУ функции, а НЕ на ее реализацию
т.е. просто вместо передачи 1-го интерфейса с 3-мя методами вы передаете 3 мелких ИНТЕРФЕЙСА-функции
А как известно из принципов SOLID "лучше несколько мелких интерфейсов, чем один большой"
Так что все с точностью наоборот :)


Можно и наследование использовать. Если нет возможности, то интерфейс.
Извините, не согласен. Насколько я знаю, должно быть как раз наоборот. Не буду долго объяснять, просто процитирую труд Гаммы, Хелма и других товарищей из Gang Of Four "Design Patterns:Elements of Reusable Object-Oriented Software":


предпочитайте композицию наследованию класса


Вы совершенно правы, но иногда не хочется открывать наружу функции, а тупо объявить protected и перегрузить,
да и громоздить композицию (т.е. наращивать объемы кода, который придется поддерживать) раньше времени не стоит
Тут все диктует конкретная ситуация, причем эта ситуация меняется вместе с проектом.
Сначала можно сделать наследованием. Если эта часть системы не расширяется - зашибись, расширяется - переходим на композицию. А раньше времени переходить - себе дороже.

alatar
10.01.2011, 01:14
Функция не есть интерфейс, вы не можете быть уверены, что вам передадут функцию с нужными параметрами.

dimarik
10.01.2011, 01:14
Тут тоже процитирую GoF:

Вот Гофов люблю. Добавил Вам кармы. Но они здесь не в тему.
Да, мы тоже знаем, что в огороде бузина, а в Киеве дядька. Вы не в той тональности поете. Очень жаль.

expl
10.01.2011, 01:24
Функция не есть интерфейс, вы не можете быть уверены, что вам передадут функцию с нужными параметрами.

Я гипотетически, представте, что мы программируем на haXe.
ИМХО если бы была типизация функций, способ с передачей 3-х функций был бы действительно лучше.

alatar
10.01.2011, 01:30
Честно говоря слабо представляю себе ситуацию, в которой классу нужны аж три функции (которые можно заменить интерфейсом) и они при этом не могут быть частью одного класса. Хотя собственно представляю, но это будут утилиты, а они не подпадают ни под интерфейсы, ни под передачу функций.

iNils
10.01.2011, 01:39
Извините, не согласен. Насколько я знаю, должно быть как раз наоборот. Не буду долго объяснять, просто процитирую труд Гаммы, Хелма и других товарищей из Gang Of Four "Design Patterns:Elements of Reusable Object-Oriented Software":Советы, особенно абстрактные, являются лишь советами, а не руководством к действию и не затрагивают конкретные случаи.

Котяра
10.01.2011, 01:44
Давно ещё поднимал тему про сигнатуры функций (http://www.flasher.ru/forum/showthread.php?t=131484). Из обсуждений вывел для себя, что единственный выход использовать классы ,т.е. интерфейсы, в вашей интерпретации этого слова.

dimarik
10.01.2011, 03:32
Передавая классу функцию Вы завязываете этот класс на СИГНАТУРУ функции, а НЕ на ее реализацию


Классу функцию передают гораздо реже, чем методу ссылку на метод. Почувствуйте, пожалуйста, разницу. Употребление термина "класс" явно не уместно в данном контексте. Здесь, скорее, должен стоять "объект". Просто закройте глаза и представьте. Методу передают параметры. Сам метод принимает аргументы. Метод может принять в качестве аргумента ссылку на объект Function, который является методом.

Тогда и с сигнатурами станет понятнее. Ваш пост претендовал на раскрытие истины, потому поправляю Ваши рассуждения.

По поводу as1-as2. Мысли вслух.
Мне жаль тех людей, которые хаят инструменты. Такое впечатление, что их кто-то заставлял работать с китайским промом и теперь по этому поводу они жалуются на неудавшуюся жизнь.
В свое время я уделял железкам (выбор слесарки, столярки) особое внимание, потому они служат мне по сей день.
Было время, был один язык. Его сменил второй, третий. Ну нет генериков, не беда, сделай хорошо без них. Мне нравился as1, мне нравился as2. Мне нравилось программирование вообще.

Вероятно, я могу быть неправ.

passertm
10.01.2011, 12:56
Разговор очень стремится выйти за пределы темы.
Преимушество Интрефейсов о котором я вспомнил позже и почемуто не написал это контроль количества параметров. полезная весч(но учитывая что никто не запрешает в листенер mousedown передавать обработчик mousemove, контроль количества ИМХО добавляет очень маленкую зашиту от ошибок)

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


Еще подумалось в джава слушатель лоджен наследовать интерфейс. даже если в интерфейсе один класс(но в джава йункции нельзя передавать). А в AS3 разработчики не стали так делать.

Добавлено через 3 минуты
Вопросы не менее расплывчаты.
Так я же вас не упрекаю. Понятно что сложно однозначно отвечать.

Какое отношение некие классы имеют к undo/redo?
В обьектах этих классов можно делать undo/redo

Я бы реализовал undo/redo командами, и они бы имели интерфейс.
Можно перефразировать. А то чето никак не пойму как это "они бы имели интерфейс"

Добавлено через 7 минут

принцип объектно-ориентированного проектирования для повторного использования: программи-
руйте в соответствии с интерфейсом, а не с реализацией.

Так я по ним и программирую. И оба этих метода "в соответствии с интерфейсом"

Добавлено через 8 минут
А потом я читаю твой код. И он делает меня печальным.
))
именно это и заставило меня начать эту тему)

alatar
10.01.2011, 13:05
А то чето никак не пойму как это "они бы имели интерфейс"
Команда, в данном случае, класс реализующий паттерн Command. И для команд которые могут быть отменены, я бы добавил интерфейс. Что бы можно было их добавлять в менеджер undo/redo.

passertm
10.01.2011, 13:10
Команда, в данном случае, класс реализующий паттерн Command. И для команд которые могут быть отменены, я бы добавил интерфейс. Что бы можно было их добавлять в менеджер undo/redo.
А.... Ну я так и сделал)

alatar
10.01.2011, 13:16
Тогда возникает вопрос: зачем передавать функции? Я для себя вижу необходимость (пожалуй даже возможность применения) передачи функции, только для всякого рода filterFunction (хотя тут можно обойтись и объектом) и easingFunction / labelFunction.

passertm
10.01.2011, 13:24
Так решив проблему таким методом, я пошел более сложным но, более привычным и проверенным способом.
Но никто не доказал что функциями в будушем возниклибы проблемы какие то. Что и пытаюсь выяснить этой темой.
Кроме того сложно решится выкинуть такую удобную возможность как передача функций.

alatar
10.01.2011, 13:31
Т.е. передача функции с неверным типом / количеством параметров и последующий отлов RTE для вас не проблема? При условии, что не всегда очевидно откуда эта функция пришла и без документации проблематично определить какие параметры должны в ней быть.

passertm
10.01.2011, 14:20
Т.е. передача функции с неверным типом / количеством параметров
Возможная(!) передача.
Я очень не любил ошибаться в трех языках(ниже написано в каких). А использование не интерфейсов добавляет один возможный РТЭ к сушествуюшим 1000(хотя ваше нежелание плодить места где можно позже ошибится мне понятно).


(чуть-чуть отойдя от темы)
а не любил я ошибатся
в Ассемблере- потому что он тупо зависал. IP начало указывать не туда и по симптомам (даже после перезагрузки) очень сложно понять где что то не так пошло.
в GCC. кто на нем писал знаком с фразой "segmentation fault"
и когда на турбоС заменял прерывание клавиатуры. где при ошибке просто вся система зависала(т.к. клавы нет).

alatar
10.01.2011, 14:32
Возможная(!) передача.
Если что-то возможно, то оно обязательно случится.
хотя ваше нежелание плодить места где можно позже ошибится мне понятно
У меня большое нежелание плодить места, где смогут ошибиться те, кто будет использовать код после меня.
Я очень не любил ошибаться в трех языках(ниже написано в каких).
Чем вызвана ваша любовь ошибаться в as? К чему это было вообще сказано? В данном случае ошибка будет не менее приятной, чем в приведенных вами примерах. Если, конечно речь не идет о наколенном проекте, на один день работы.

passertm
10.01.2011, 15:15
В данном случае ошибка будет не менее приятной, чем в приведенных вами примерах. Если, конечно речь не идет о наколенном проекте, на один день работы.
Нонимаете если все было бы настолько плохо и каждая не правильно переданная переменная отнимало бы день ни одна программа не дописывалась бы.

Чем вызвана ваша любовь ошибаться в as? К чему это было вообще сказано?
К тому что бывают случаи где лучше не ошибатся. Там для нахождения этой ошибки может притись удалить все что вы написали и по частям добавлять коды в программу чтобы знать в каком куске искать ошибку.

а тут нахождения подобных ошибок имхо займет совсем не много времени.