Как создать древовидную иерархическую структуру с уникальным поведением для каждой комбинации типов? - PullRequest
0 голосов
/ 24 февраля 2019

Предположим:

  1. Есть некоторый модуль с интерфейсом IA.
  2. Есть некоторый модуль B, который принимает в параметре экземпляр IAи чье поведение зависит от типа этого IA,

значения (псевдокод, без определенного языка, [хотя я использую Python])

class B{
    IA ia;
    B(IA ia){
        this.ia = ia;
    }
    doStuff(){
        if(type(this.ia)==A1){
             print("A1");
        }
        if(type(this.ia)==A2){
             print("A2");
        }
    }
}

IПонимаю, что я мог бы добавить какой-нибудь открытый метод foo к ia, и, таким образом, код упростится до

class B{
    IA ia;
    B(IA ia){
        this.ia = ia;
    }
    doStuff(){
        this.ia.foo();
    }
}

Мой вопрос состоит из двух частей:

  1. Каков правильный дизайн для достижения этой цели, если я (по какой-то причине) не могу изменить IA, то есть я не могу добавить foo()?

  2. Каков правильный (масштабируемый) дизайн, если мне разрешено изменять IA, но теперь та же проблема повторяется для A1, A2 и т. Д., Что означает

конечное желаемое поведение -

class B{
    IA ia;
    B(IA ia){
        this.ia = ia;
    }
    doStuff(){
        if(type(this.ia)==A1){
             if(type(this.ia.iz)==Z1){
                 print("A1Z1");
                 print("unique treatment");
             }
             if(type(this.ia.iz)==Z2){
                 print("A1Z2");
                 print("special treatment");
             }
        }
        if(type(this.ia)==A2){
             if(type(this.ia.iz)==Z1){
                 print("Z1A2");
                 print("one of a kind treatment");
             }
             if(type(this.ia.iz)==Z2){
                 print("Z2A2");
                 print("Wow treatment");
             }
        }
    }
}

и может повторяться несколько раз.

Обратите внимание, что Z1 и Z1 одинаковы для A1 и A2! .И снова, то же самое может продолжаться, IZ может содержать IX нескольких типов с уникальным поведением

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

Мне все еще не нравится проверка типов, и я задаюсь вопросом, можно ли что-то сделать, что выглядит лучше.

Ответы [ 2 ]

0 голосов
/ 24 февраля 2019

Возможно, вы захотите взглянуть на шаблон посетителя (https://en.wikipedia.org/wiki/Visitor_pattern).. Это предполагает, что вы можете изменить IA и друзей, чтобы реализовать accept методы

.
0 голосов
/ 24 февраля 2019

Я думаю, что вы ищете Tagged Union Types .Также рассмотрим Существуют ли на самом деле типы объединения в Python?

Некоторыми примерами могут быть Запечатанные классы Котлина и Оператор When .Или Классы дел Кейса и Запечатанные Черты .

Если вы используете Java, настроить его будет несколько словесно, используя Paguro .

interface Wheeled { }

class Beetle implements Wheeled { }

class Truck implements Wheeled { }

// Makes a union class.
static class Beetle_Truck extends OneOf2<Beetle,Truck> {
    private Beetle_Truck(Object o, int n) {
        super(o, Beetle.class, Truck.class, n);
    }

    static Beetle_Truck ofBeetle(Beetle b) {
        return new Beetle_Truck(b, 0);
    }
    static Beetle_Truck ofTruck(Truck t) {
        return new Beetle_Truck(t, 1);
    }
}

// Here's where we use it.
@Test public void testBeetleTruck() {
    Beetle_Truck bt1 = Beetle_Truck.ofBeetle(new Beetle());
    Beetle_Truck bt2 = Beetle_Truck.ofTruck(new Truck());

    assertEquals("b", bt1.match(beetle -> "b",
                                truck -> "t"));

    assertEquals("t", bt2.match(beetle -> "b",
                                truck -> "t"));
}

Обратите внимание, что Beetle и Truck не нужнореализовать общий интерфейс на всех.Что касается вашего второго вопроса, вы можете просто сделать OneOf4, похожий на OneOf2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...