Рубрики
Без рубрики

Почему интерфейсы Java не ужасны (просто строгие)

В недавней статье были описаны некоторые проблемы при работе с интерфейсами Java, com… Помеченный как java, кодирование.

В недавней статье описывались некоторые проблемы при работе с интерфейсами Java, исходящие из языка, который допускает утиный ввод.

Суть вот в чем. Есть интерфейс:

public interface DynamoImpl {
  public PutItemResult putItem(PutItemRequest putItemRequest);

  public GetItemResult getItem(GetItemRequest getItemRequest);
}

И есть класс Amazon DynamoDB . Этот класс имеет два вышеуказанных метода, но также и многое другое. Теперь Джон, программист, хочет предоставить только эти два метода Amazon DynamoDB остальной части своей программы. Он хочет использовать их в своем классе База данных :

public class Database {
    public DynamoImpl db;

    // code removed for simplicity

    public Database(DynamoImpl db) {
        this.db = db;
    }
}

Теперь: на языке, поддерживающем утиный ввод, вы могли бы просто передать экземпляр class Amazon DynamoDB в конструктор и вызовите два метода (потому что они есть в классе). Но только не на Яве. Вам нужно передать экземпляр класса, который буквально реализует интерфейс DynamoImpl (или расширяет класс, который делает это). Но Amazon DynamoDB

Самый простой способ достичь той же цели в Java – создать оболочку, которая делегирует экземпляр Amazon DynamoDB |/:

public class AmazonDynamoDbWrapper implements DynamoImpl{

    private AmazonDynamoDB amazonDynamoDB;

    public AmazonDynamoDbWrapper(AmazonDynamoDB amazonDynamoDB) {
        this.amazonDynamoDB = amazonDynamoDB;
    }

    @Override
    public PutItemResult putItem(PutItemRequest putItemRequest) {
        return amazonDynamoDB.putItem(putItemRequest);
    }

    @Override
    public GetItemResult getItem(GetItemRequest getItemRequest) {
        return amazonDynamoDB.getItem(getItemRequest);
    }

}

Да, немного многословно, но довольно просто, как только вы поймете шаблон. Теперь вы можете передать экземпляр этого класса экземпляру Database .

Вот и все для производственного кода. А как насчет тестов?

Самое простое решение – обеспечить минимальную реализацию интерфейса Dynamo Impl , например:

public class StubbedDynamoImpl implements DynamoImpl {

    @Override
    public PutItemResult putItem(PutItemRequest putItemRequest) {
        return new PutItemResult(/* Test data here */);
    }

    @Override
    public GetItemResult getItem(GetItemRequest getItemRequest) {
        return new GetItemResult(/* Test data here */);
    }
}

Опять же, вы можете передать экземпляр этого класса в Опять же, вы можете передать экземпляр этого класса в

public class DatabaseTest {

    @Test
    public void createsDatabase() {
        Database database = new Database(new StubbedDynamoImpl());
        // Whatever your test assertions are, here
    }
    // ...
}

Нет необходимости в причудливых издевательских фреймворках, если все, что вы хотите показать, – это два метода. Это самое простое решение, которое я мог придумать. Я надеюсь, что это полезно.

P.S. Одно слово относительно соглашений Java: пожалуйста, не используйте суффикс Impl для интерфейсов. Это должно использоваться для конкретных классов реализации (если вообще используется), иначе вы можете запутать многих людей.

Оригинал: “https://dev.to/bertilmuth/why-java-interfaces-arent-terrible-just-strict-3de2”