Java - Есть ли такая вещь, как слишком много интерфейсов? - PullRequest
0 голосов
/ 14 ноября 2018

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

Я никогда полностью не понимал их пользу. Я всегда думал, что «почему бы просто не написать методы нормально». Это всего лишь методы. А потом я начал изучать внедрение зависимостей и то, как он действительно упрощает код, чтобы конструктор был главной точкой контакта с внешним миром для класса.

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

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

Для разработчиков Java, знающих всю мощь интерфейсов, этот небольшой фрагмент кода, который я написал, иллюстрирует хороший паттерн или хорошее мышление? В основном это хороший код? Я просто хотел бы знать, нахожусь ли я на правильном пути. Завтра у меня второе собеседование на работу, и я хотел бы рассказать об этом во время собеседования, если и только если я на верном пути.

Вот код:

interface Fightable{
void kick(Fightable enemy);
void punch(Fightable enemy);
void takeDamage(Fightable enemy, String typeOfStrike);
void strikeEnemy(Fightable enemy, String typeOfStrike);
}

interface CanEat{
void chew();
void swallow();
}

interface MotherShip{
int motherShipBoost = 50;
String getColony();
void sendHelp(int[] location);
String buildMoreShips(int amount);
void flyToNewSystem(String newSystem);
int[] beamDownRandomly();
}

interface Animatable{
void animateChew(CanEat eater);
void animateSwallow(CanEat eater);
void animateMove(Moveable mover);
void animateRevive(CanEat eater);
void animateStrike(Fightable striker, Fightable receiver, String typeOfStrike);
}

interface Moveable{
void setNewLocation(int []newLocation);
int[] getLocation();
void move();
}

public class GameCharacter implements Fightable, CanEat, Moveable{

private int health;
private String name;
private int[] location;
private String stamina;
private String origin;
private String colony;
private Animatable animator;
private MotherShip motherShip;
private boolean isRecruited;

public GameCharacter(MotherShip motherShip, String name, Animatable animator){
    this.motherShip = motherShip;
    this.animator = animator;
    this.name = name;
    this.location=this.motherShip.beamDownRandomly();
    this.colony = this.motherShip.getColony();
}


@Override
public void kick(Fightable enemy) {
    strikeEnemy(enemy, "KICK");

}



@Override
public void punch(Fightable enemy) {
    strikeEnemy(enemy, "PUNCH");
}

@Override
public void takeDamage(Fightable enemy, String typeOfHit) {
    this.health = this.health - 3;
    animator.animateStrike(enemy, this, typeOfHit);
    if(this.health < 10){
        motherShip.sendHelp(this.location);
    }
}

@Override
public void strikeEnemy(Fightable enemy, String typeOfStrike) {
    enemy.takeDamage(this, typeOfStrike);
    animator.animateStrike(this, enemy, typeOfStrike);
}

@Override
public void chew() {
    animator.animateChew(this);

}

@Override
public void swallow() {
    animator.animateSwallow(this);
    health = health + 10;
    animator.animateRevive(this);
}

@Override
public void setNewLocation(int[] newLocation) {
    this.location = newLocation;
}

@Override
public int[] getLocation() {
    return this.location;
}

@Override
public void move() {
    animator.animateMove(this);
}
}

Похоже, у меня правильная идея?

Спасибо за любые отзывы

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Я постараюсь как можно лучше ответить на ваш вопрос как можно лучше.

1

Полезно ли абстрагировать как можно больше функциональных возможностей в интерфейсы? Давайте начнем с основ a) Помните, что интерфейсы - это не что иное, как «контракты», обещание, что субъект, реализующий интерфейс, в основном обещает соблюдать и выполнять условия контрактов. б) Интерфейсы выступают в качестве отличных инструментов проектирования в коде, позволяя, по сути, продюсеру и актерам сосредоточиться на высоком уровне взаимодействия, не беспокоясь о деталях реализации.

С точки зрения непрофессионала CS, интерфейс обещает соответствие, по сути, 3 вещи. 1. обещание, что упомянутая функциональность / операция / функция / метод доступна 2. что этот функционал принимает указанный согласованный вклад 3. что (если реализовано) эта функциональность даст указанные результаты.

Таким образом, когда часть услуги (сообщение класса / мыла и т. Д.) Предлагает нам реализовать интерфейс, она публично соглашается с этими тремя условиями «контракта», и любое отклонение от них является нарушением контракта.

2

Да, вы абсолютно правы, интерфейсы действительно демонстрируют свою мощь, когда дело доходит до Ioc (инверсия управления) в Принципы проектирования SOLID , которые позволяют контейнеру IoC разрешать (предоставлять) и обслуживать подходящий субъект (реализация), который выполняет контракт, часто во время выполнения, поэтому освобождает разработчика системы, чтобы он не беспокоился о деталях реализации.

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

Один разработчик В качестве примера я занят написанием новой системы программного обеспечения и в течение дня я сосредоточил свое внимание на том типе функциональности, который я хотел бы предложить своим пользователям, возможно, иметь возможность управлять их списком задач в общем смысле, что влечет за собой возможность «создавать» новые элементы задач, «проверять» существующие элементы и «удалять» элементы из их коллекции задач. Теперь есть несколько способов реализации каждой из этих функций, и я становлюсь ленивым. Я предпочел бы потратить следующую неделю на предоставление только одной из этих функций, но я мог бы забыть свои первоначальные мысли и в конечном итоге реализовать свои собственные функции на основе что касается моего влияния с течением времени, чтобы дисциплинировать себя и придерживаться того, что я изначально придумал, я предпочел скорее составить проект контракта на эту функциональность заранее, фактически не реализовав его, что позволит мне имитировать эти функции, а не фактически их реализовывать. Таким образом, используя интерфейсы, я заложил основы того, чего мне нужно достичь в ближайшие недели, и я могу возвращаться к нему через день и дополнять свои функции, не нарушая своего обещания ... что подводит нас к следующей теме, которая Я не буду слишком углубляться в принципы Open Close (O в SOLID), которые в основном говорят, что мои проекты закрыты для внешних изменений, но открыты для внутренних изменений и, возможно, событий, открытых для расширения (дополнения). поэтому я могу добавлять новые функции в свой сервис todo, не нарушая свои существующие контракты, и я могу изменить их поведение при реализации, но не могу изменить форму существующих функций.

В команде Я работаю с Lindile и Selebalo над внедрением системы виртуальных карт, и поскольку работы слишком много, мы решили, что я сосредоточусь на основной банковской системе (бухгалтерская книга баланса), а Lindile сосредоточится на депозитах ВК, а Selebalo - на депозитах. депозиты ВК. Во время нашей первоначальной сессии проектирования мы разрабатываем изнутри, начиная с основного банковского дела, и описываем, какие операции будут доступны для обновления учетной записи клиента, и после нескольких часов обсуждений мы решаем, что основная банковская система предложит две функциональные возможности, одну для добавления деньги на счет, называемый «кредит», который принимает сумму, и «дебет», который вычитает или уменьшает счет клиента, который также принимает сумму. Но поскольку ядро ​​должно иметь дело со многими другими вещами (кредитные профили клиентов, AML и т. Д.), Кроме дебетов и кредитов, это может занять некоторое время, пока я не скажу, что ребята могут интегрировать и тестировать свои коды, поэтому мы принимаем решение по контракту основной банк, который имеет

public interface ICoreBankingServices{

Balance Debit(decimal amount,Currency c);
Balance Credit(decimal amount, Currency c);

}

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

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

Я не ожидаю Java, но если игровой персонаж должен сражаться, есть и двигаться, вы на правильном пути. Вам просто нужно следить за уровнем развязки, который вы делаете (так же, как нормализация) за счет увеличения сложности, но нет никаких указаний для этого, и пока вещи не становятся слишком сложными, вы можете описать вещи в много интерфейсов, насколько это логически возможно ... просто не применяют одно и то же мышление, когда речь идет о множественном наследовании реализации, но это личное мнение :)

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

0 голосов
/ 14 ноября 2018

Сначала существует интерфейс для реализации всех описанных в нем методов, отличных от заданных по умолчанию.Это может быть легко заменено абстрактным классом.Однако для упрощения санации были реализованы интерфейсы.

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

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

Более того, Javaне поддерживает множественное наследование в случае класса.Таким образом, используя интерфейс, вы можете иметь множественное наследование, как и в вашем примере.

Действительно хорошая работа и удача в интервью!

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