LINUX.ORG.RU

Объектно-ориентированный дизайн

 , , , ,


0

1

ЛОР, а как ты предпочитаешь реализовывать подобного рода конструкции?

Казалось бы doSpecificComplexTask() нужно сделать методом Link и переопределить его в каждом наследнике, но что если в этом методе может быть довольно нетривиальной код, который хочется держать отдельно от данных (например, работа с сетью, базой, etc...). Т.е. хочется, чтобы класс Link был скорее структурой?

Visitor - очень громоздко, instanceof - в Java говорят плохой стиль. Хотя если разобраться, то чем Pattern Matching из Scala не instanceof?

Да, это ООП головного мозга.

Java:

public interface Entity {
    String getId();
    String getMessaage();
    Link getLink();
}

public interface Link {
    
    void accept(Visitor visitor);

    static interface Visitor {
        visit(UrlLink link);
        visit(SomethingElseLink link);
        visit(EvenMoreLink link);
    }    

    static abstract class UrlLink() implements Link {
        void accept(Visitor visitor) { visitor.accept(this); }
        URL getURL();
    }

    static abstract class SomethingElseLink() implements Link {
        void accept(Visitor visitor) { visitor.accept(this); }
        SomethingElse getSomethingElse();
        AndSomethingElse getAndSomethingElse();
    }

    static abstract class EvenMoreLink() implements Link {
        void accept(Visitor visitor) { visitor.accept(this); }
        EvenMore getEvenMore();
    }

}

// Variant 1

class SpecificVisitor implements Link.Visitor { ... }

SpecificVisitor visitor = new SpecificVisitor();
entity.getLink().accept(visitor);

// Variant 2

Link link = entity.getLink();
if (link instanceof UrlLink) { doSpecificComplexTask(...); }
if (link instanceof SomethingElseLink) { doSpecificComplexTask(...); }
if (link instanceof EvenMoreLink) { doSpecificComplexTask(...); }

Scala:

class Entity(id: String, message: String, link: Link)

trait Link
case class UrlLink(url: URL)
case class SomethingElseLink(se: SomethingElse, ase: AndSomethingElse)
case class EvenMoreLink(em: EvenMore)

entity match {
    case UrlLink(url) => doSpecificComplexTask(url)
    case SomethingElseLink(se, ase) => doSpecificComplexTask(se, ase)
    case EvenMoreLink(em) => doSpecificComplexTask(em)
}
★★
Ответ на: комментарий от qulinxao

Из этого чеклиста точно нету. Ты лучше не теоретизируй, а предложи свой вариант на языке, который чаще всего используешь. Это будет куда как более конструктивно.

Спасибо.

Ian ★★
() автор топика
Ответ на: комментарий от Ian

ок, пойдём с основ.

скажи, для делает(в смысле предназначения , а не механики) твой код? т.е расскажи текст говоримый утёнку?

qulinxao ★★☆
()
Ответ на: комментарий от qulinxao

Вводить в контекст конкретно моей задачи не хочется, он просто слишком большой и мне придется многое пояснять. Мне кажется из примера должно быть вполне понятно о чем идет речь. Есть сущность Entity, у которой есть свойство (пусть будет Property). Это свойство выделено семантически. Т.е. это нечто присущее Entity, но вариантов реализации этого чего-то может быть несколько... Вот может не самый удачный пример, но схожий с моей задачей. Есть меню, у которого есть элемнты. У элемента есть ссылка, которая может быть URL (или даже URI), а может быть какой-то compound id - ссылка на внутренний объект системы.

Ian ★★
() автор топика
Последнее исправление: Ian (всего исправлений: 1)
Ответ на: комментарий от Ian

где в т.ч. _не_будет_ динамики, а в остальных случаях хватит тогоже дизайна с «ужасным» case хоть по названию класа - или цепочки if(instanceof) главное чтобы читалось просто, чем визитор в указанной реализации не блещет

Deleted
()
Ответ на: комментарий от Deleted

Согласен, у visitor с читаемостью плохо. Но зато compile-time проверка, что ничего не забыл.

Ian ★★
() автор топика
Ответ на: комментарий от Ian

а сменить

entity.getLink().accept(visitor);

на

visitor.accept(entity.getLink());

его придется переименовать, да меньше будет напрашиваться слов при виде этого кода, а проверка реализуется посредством

Visitor<L extends Link> {accept(L link)}

который в compile time заменится на тупые касты, но если тебе сильно хочется секса с конпелятором

Deleted
()
Ответ на: комментарий от Deleted

а то вот чесслово, когда встречаю подобный код, который раз в 10 запутан только ради следования тупым шаблонам, хочется пойти в церковь и сдать эту тоталитарную секту Паттернопоклонников

Deleted
()

Если в 2-х словах, то ты хочешь multiple dispatch.

В языках с single dispatch он реалезуется с помощью visitor либо instanceof.

pitekantrop ★★★
()
Ответ на: комментарий от anonymous

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

То, что ты осилил жабу, сишарп либо какой-нибудь другой вижуал бейсик и клепаешь теперь веб-морды к БД за пару килобаксов в месяц, не делает тебя специалистом в языках программирования. Так что твоё мнение насчет нужности монад никому не интересно. Твой удел — писаться кипятком, когда очередной Эрик Майер адаптирует их и выкатит вам в качестве LINQ.

pitekantrop ★★★
()
Ответ на: комментарий от vtVitus

instanceof плох тем, что выполняется в runtime, использует reflection, и выполняется относительно медленно.

Насчёт scala pattern matching не знаю, не копал в эту сторону.. может, компилятор там какие оптимизации проводит?.. ибо тут нет ничего невозможного.

BattleCoder ★★★★★
()
Ответ на: комментарий от BattleCoder

1. Это мифы времён java 1.0.

2. Когда я вижу людей, которые рассуждают про оптимизации на таких уровнях в java, мне хочется им чего-нить плохое сделать. Чтоб потом не иметь чести видеть их «оптимизированный» код.

Вопрос на засыпку сколько миллионов instanceof выполнится на десктопной машине в секунду. У меня 159427142 per 1 second .

vtVitus ★★★★★
()
Последнее исправление: vtVitus (всего исправлений: 1)
Ответ на: комментарий от vtVitus

Да, вы правы. Голословные утверждения с моей стороны. Основанные на «одна бабка сказала». Ведь это так легко проверить, просто цикл набросать в коде. Займусь этим как найду время.

BattleCoder ★★★★★
()
Ответ на: комментарий от anonymous

копаешься в акаменелых останках мамонтов? архиолух, лол

Karapuz ★★★★★
()
Ответ на: комментарий от pitekantrop

lol а ты на чем деньги подымаешь мил. человек? 90% что говнокодя на java. Ты как бы живое подтверждение, что манады не нужны, даже тем кто их выучил :D.

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

Да java, хотя есть большая вероятность, что скоро большую часть времени буду писать на scala. Сейчас я занимаюсь, в основном, разработкой либ и фреймворков за деньги, которые потом используют ынтырпрайз-программисты. Так что имею больше прав судить, что нужно в языке, чем «профессионалы», знания и навыки которых — это знания каких-то API и умение их вызывать.

Если кому-то что-то не нужно — пишите: «мне не нужно». Мне вот и лямбды нужны, и ADT с паттерн матчингом, и нормальная система типов. Чтобы быстрее и качественнее делать продукт для тех, кто стоит ниже меня в пищевой пирамиде.

pitekantrop ★★★
()
Ответ на: комментарий от Ian

Конкретнее double dispatch. Thanks cap!

Если знаешь, как это называется, то можно нагуглить способы эмуляции этого в своём любимом языке программирования за минуту.

pitekantrop ★★★
()

Ваше решение - к ООП не имеет отношения. Можно сказать, что это ООП вывернутое наизнанку. Отсюда и сложности.

anonymous
()
Ответ на: комментарий от anonymous

Не сочтите за обиду, конечно. Я хотел только подчеркнуть, что вы сконцентрировались на структуре Entity, а нужно было на поведении.

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

Потому что entity - это не объект, а структура. И наличие данных без поведения ООП абсолютно не отрицает. Прочитайте начало поста. Я написал там про полиморфный метод-поведение и почему такое решение не подходит.

Ian ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.