- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
public class ImageWorkerSingleton
{
private static ImageWorkerSingleton instance;
private ImageWorkerSingleton() { }
public static ImageWorkerSingleton Instance
{
get
{
if (instance == null)
{
instance = new ImageWorkerSingleton();
}
return instance;
}
}
public void Init() {}
public string UrlToImage(Guid id, ImageTypeEnum imageType = ImageTypeEnum.PhotoUndefined)
{
...
}
public bool IsImageExist(Guid id, ImageTypeEnum imageType = ImageTypeEnum.PhotoUndefined)
{
...
}
}
bormand 20.06.2012 14:59 # +5
Статические методы автора уже не возбуждали...
DarkThinker 20.06.2012 15:30 # +1
roman-kashitsyn 20.06.2012 15:36 # +1
abatishchev 20.06.2012 23:09 # 0
отнюдь. они дешевле
roman-kashitsyn 21.06.2012 01:42 # +1
Ты хоть понимаешь, что если файл с изображением лежит на диске, то один вызов Exists будет стоить в сотни раз дороже, чем конструирование объекта ImagePath?
Я не говорю, что статические методы не нужны. Они нужны редко, например, для фабричных методов (в Java это даже помогает унылому выводу типов-параметров обобщённых классов), для оформления утилитных функций в идиотской модели "всё лежит внутри класса", принятой в Java и C#, ведь гораздо более естественной формой для вещей вроде StringUtils является не класс со статическими методами, а пакет/пространство имен/модуль с набором обыкновенных функций.
И ещё они нужны для дебилов, которые пишут статические методы с кучей побочных эффектов ради сиюминутной выгоды, многократно усложняя тестирование и повторное использование кода.
Удивляюсь до чего разумные люди работали над Scala: выкинули статику нахрен и сделали всё по человечески.
Steve_Brown 21.06.2012 10:38 # +2
Стоит ли вместо
писать
или
? Хотя, конечно, объект ImagePath можно хранить и передавать в качестве аргументов.
roman-kashitsyn 21.06.2012 10:47 # +2
Да, он нужен именно для того, чтобы не таскать одну и ту же пачку параметров в сигнатурах методов.
Я не особо пишу на c#, в Java, например, для работы с File (на самом деле там это Path) нужно создавать объект, и у него есть метод exists. Когда параметров мало и они примитивны (у обычного Path это одна строка), разницы нет. Когда параметров становится больше и они могут меняться со временем, объектный подход получает преимущества в удобстве работы и сопровождения.
koodeer 21.06.2012 14:57 # +2
Согласен, что в разных случаях удобней разные подходы.
3.14159265 21.06.2012 14:19 # +2
Не надо тут переиначивать. Причём тут конкретная задача ImagePath? Тебе говорят, о том что в целом статика дешевле - это аргумент.
Конкретно пример - new Integer(a) и Integer.valueOf(a).
От статических методов есть несомененная польза. По-прежнему есть люди, которые пишут структурно, не сильно заморачиваясь ООП, особенно там где оно нахер не нужно.
На мой вкус equals(a,b) выглядит красивей чем a.equals(b) и позволит избежать boilerpalte проверок чтоб не получить NPE.
P.S. Редчайший случай, когда я с тобой не согласен, и полностью разделяю мнение оппонента.
roman-kashitsyn 21.06.2012 14:51 # +1
Это фабричный метод, я их очень люблю, и об этом и написал.
> equals(a,b) выглядит красивей чем a.equals(b)
equal(a,b) можно убрать из объекта и сделать полиморфным только в том случае, если в языке есть мультиметоды, которых ни в java, ни в c# не наблюдается. От a.equals(b) никуда не денешься. Проблема с NPE - epic fail разработчиков Java. В Scala, к примеру, оператор == работает как правильный equal(a, b), для сравнения адресов используется eq. К тому же, это как раз относится ко второму случаю (с библиотеками простых функций), когда статики нужны в наших кривоватых ЯП.
3.14159265 21.06.2012 14:57 # 0
Мы сейчас говорим о Java/C#. И в этих языках статик-методы (extension-методы) позволяют избежать многих подобных проблем.
>Это фабричный метод, я их очень люблю, и об этом и написал.
Я внимательно прочитал то что написал
>помогает унылому выводу типов-параметров
Речь шла о удобстве женериков в методах (хитрый автовывод, которого нет в конструкторах) и ограничениях на то что вызов super - всегда первый.
А я и abatishchev говорим о том что статика позволяет не плодить ненужных, лишних объектов для выполнения простых действий: юзать старые или выполнять действия над существующими.
>А если пакетик из-под чая не выбрасывать, а использовать несколько раз
Это как раз пример с Integer и кешем.
roman-kashitsyn 21.06.2012 15:08 # 0
Если у нам нужно сделать, к примеру, сервис синглтоном (т.е. нам нужен только один объект), это не значит, что нужно делать его методы статическими. Достаточно дать хинт DI фрэймворку, чтобы он создавал ровно один объект и использовал его повторно.
По поводу Integer и кэша - никто не запрещает сделать у ImagePath фабричный метод и кэшировать часто используемые пути (или правильней - спрятать кэш в вызов сервиса c GetPath). Это вещь, перпендикулярная полиморфности/статичности Exists и URL.
3.14159265 21.06.2012 15:40 # 0
Я понял к чему ты клонишь. Статик-методы не нужны редко - юзайте di-фреймворки.
>никто не запрещает сделать у ImagePath фабричный метод
И он ессно будет статическим.
>спрятать кэш в вызов сервиса c GetPath
А вот этого не хотет.
Этого будет достаточно
public static ImagePath on(Guid id, ImageType imageType);
вызывать так
ImagePath.on(guid,type).setUrl(url)
Хотя вопрос конечно спорный и всё зависит от конкретной ситуации.
roman-kashitsyn 21.06.2012 15:46 # +1
Повторюсь, статика предпочтительна для
1. Фабричных методов
2. Утилитных функций, не вписывающихся в ООП (new StringUtils().join() o_O)
> А вот этого не хотет.
Чем мне не нравится кэш ImagePath в самом ImagePath - пути к каталогам нужно конфигурить, а схемы сохранения могут быть сложными, потому впихивать разборы конфигураций и общение хрен знает с чем в простые DTOшки как-то некошерно.
roman-kashitsyn 21.06.2012 15:26 # 0
Но это - исключительные ситуации, которые встречаются нынче нечасто.
Просто пытаюсь донести своё мнение, полученное из (горького?) опыта: не нужно использовать статику только потому, что она чуть шустрее, там, где это не имеет никакого значения.
roman-kashitsyn 21.06.2012 16:30 # 0
Вообще-то, я считал, что abatishchev имеет ввиду немного другое - что вызов статического метода в VM происходит быстрее, чем вызов полиморфного (само собой, это так), т.е. invokestatic vs invokevirtual
roman-kashitsyn 21.06.2012 14:57 # 0
И вот теперь самое интересное: давайте ка попробуем потестить модуль, использующий услуги по получению текущего пользователя. Если с инжекцией всё просто - подкинь стаб и готово - то со статиками нужно использовать чёрную магию PowerMock или честно поднимать спринговый контекст и класть туда стаб.
3.14159265 21.06.2012 15:13 # 0
А я это дело недолюбливаю.
>Гораздо удобней, чем инжекция, не так ведь?
Именно по этой причине.
>который лезет в спринговый контекст, выцепляет оттуда бин сервиса по имени
Тут проблема другая - намешали 2 парадигмы.
Если в проекте используется DI - все должны инжектить, если оперирование через статик-методы, то никто не должен пытаться внедрить IoC.
В проекте должны быть единый подход, единый стиль кодинга, единое соглашение по неймингу переменных. Причем похуй кому что не нравится - соблюдать должны все.
roman-kashitsyn 21.06.2012 15:20 # 0
3.14159265 21.06.2012 15:30 # +1
roman-kashitsyn 21.06.2012 15:35 # +1
Lure Of Chaos 22.06.2012 01:50 # +1
чаще статика полезна для классов утилит, фабрик, синглтонов. вот только не надо скатываться в процедурщину.
динамика лучше, когда есть некий контекст (кстати, фабричный метод и тут годится), и всякого рода builder'ов типа guava.
roman-kashitsyn 21.06.2012 09:50 # +1
bormand 21.06.2012 09:56 # +3
roman-kashitsyn 21.06.2012 10:05 # −1
bormand 21.06.2012 10:19 # 0
guest 22.06.2012 09:25 # −10
3.14159265 22.06.2012 13:22 # +3
Lure Of Chaos 22.06.2012 15:37 # +3
guest 22.06.2012 21:56 # −5
Lure Of Chaos 20.06.2012 15:30 # +1
Steve_Brown 20.06.2012 16:40 # +7
absolut 21.06.2012 09:13 # +1
guest 21.06.2012 23:33 # −7