Какова лучшая аналогия, чтобы помочь неопытным разработчикам программировать на основе интерфейса?

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

9 ответов

Решение

Чтобы помочь вашей команде освоиться с этой идеей, лучшим способом было бы продемонстрировать, чего может достичь разработка на основе интерфейса, и сопоставить это с тем, как без этого нужно было бы сделать то же самое. Чтобы они "действительно" приняли и начали понимать это, им сначала нужно понять и почувствовать боль проблемы, которую она решает. Им действительно нужно поговорить "Я устал от необходимости делать X каждый раз, когда происходит Y", с самим собой или с командой. Одна вещь, которую мой отец учил мне в мои "формирующие" годы, это маленькая жемчужина:

Независимо от того, сколько раз вам сказали, вы НИКОГДА не получите ответа, пока ВЫ не зададите вопрос.

Как только этот разговор происходит (инициируемый самим человеком или командой), это то место, где может происходить истинное обучение. Хитрость заключается в том, чтобы создать среду, которая будет стимулировать подобные вопросы. Если вы можете показать им, что они хотят получить ответ на проблему, которую решает интерфейс, тогда ОНИ сами зададут вопрос.

Вот один хороший пример, демонстрирующий полезность интерфейсов:

Тебе поручили быть вышибалой на международной математической конвенции. Вам сказали только позволить людям, которые могут дать правильный ответ на вопрос "Что такое два плюс два". Поскольку это международное мероприятие, естественно, многие пытаются войти на нем, говоря на разных языках. Сначала ваша тактика состоит в том, чтобы выяснить (или угадать), на каком языке говорит человек, запрашивающий вход, затем найти переводчика, говорящего на том же языке, и задать вопрос через него. Оказывается, это работает, и вскоре вы научитесь быстро распознавать некоторые языки и теперь знаете, какие переводчики говорят на этом языке, НО, конечно, это боль, когда кто-то, говорящий на языке, который вы не можете идентифицировать, обнаруживается, и вы придется потратить все это время, чтобы выяснить, что это, а затем найти подходящего переводчика. Итак, зная, что должен быть лучший способ, вы пытаетесь найти лучший способ выполнять свою работу, и именно тогда он приходит к вам. Вы получаете пачку бумаги и несколько ручек для маркировки, и каждый раз, когда кто-то подходит для участия в конвенции, вы пишете на листе бумаги следующее:

2 + 2 =

И вот, это работает! Каждый человек быстро дает ответ. Вам не нужно выяснять, на каком языке говорит человек, или найти переводчика. Черт возьми, тебя даже не волнует, на каком языке они говорят, они просто отвечают на вопрос, потому что они все знают математику! Вместо того, чтобы разбираться в каждом конкретном случае, вы использовали интерфейс "IKnowMath", который понятен каждому участнику математического соглашения.

Интерфейс - это контракт. Он просто указывает, что конкретная категория (трудно обойти слово " класс" здесь) класса должна предлагать в качестве публичного API.

Интерфейс подобен дресс-коду класса. Если класс реализует интерфейс, его открытые члены (его появление в других классах, если хотите) будут включать то, что интерфейс объявляет как минимум.

Я бы посоветовал вам показать им преимущества, которые могут быть из этого получены. Представьте себе этот сценарий на C#:

class User
{
    public String GetFirstName() { return "foo"; }
}

class App
{
    void Run()
    {
        User user = new User();
        String firstName = user.GetFirstName();
    }
}

Здесь у нас есть User класс, который пойдет и получит имя откуда-то и вернет его. Теперь ваше приложение связано с этим классом, и позже вам будет сложно изменить, откуда вы получили имя, потому что вы использовали User класс везде. Что произойдет, если вы внедрили сервис и захотите начать вызывать этот сервис для FirstName значение? Вы бы немного рефакторинг сделать.

Рассмотрим этот подход:

interface IUser
{
    String GetFirstName();
}

class User : IUser
{
    public String GetFirstName() { return "foo"; }
}

static class UserFactory
{
    public static IUser GetUser() { return new User(); }
}

class App
{
    void Run()
    {
        IUser user = UserFactory.GetUser();
        String firstName = user.GetFirstName();
    }
}

Теперь вы можете реализовать интерфейс в любом классе, который вам нравится:

class UserService : IUser
{
    public String GetFirstName() { return "bar"; }
}

и просто измените метод фабрики, как:

static class UserFactory
{
    public static IUser GetUser() { return new UserService(); }
}

и код вашего приложения не будет мудрее.

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

Аналог: возьмите трехмерный объект, как кусок трубки. В зависимости от того, в каком направлении вы смотрите на него, он выглядит ("ведет себя как") либо кругом, прямоугольником или трехмерным объектом. Концепция приведения может быть легко приравнена к "попытаться повернуть объект, чтобы вы могли заставить его выглядеть так, как вы хотите / нуждаетесь", который либо удастся, либо потерпит неудачу в зависимости от объекта и вида, который вы ищете.

Аналог не совсем на 100%, но он может помочь сделать что-то очень абстрактное для людей, которые еще не поняли концепцию, во что-то конкретное.

Копия шаблонов проектирования Head First или, по крайней мере, примеры кода из шаблонов Head First Design.

Рассказ, как то, как это было сделано в Head First Design Patterns, действительно работает много раз со скептиками.

С уважением, Эдвардс

С чем они знакомы?

Когда я изучал C++, учитель опирался на мои знания C, например:

  • Возьмите подпрограммы библиотеки C для файлового ввода-вывода: открывайте, читайте и закрывайте, используя дескриптор файла
  • Покажите, как их можно переписать как методы класса File: создать, вызвать метод read, вызвать деструктор экземпляра File.

Основываясь на этом, я мог бы сравнить интерфейс IFile с классом File, сказав, что IFile вообще не предоставляет подробностей реализации: если приложение использует IFile вместо File, вы можете изменить базовую файловую систему / детали реализации).

Скажите им, что интерфейсы - это трюковое слово. Потому что смысл скрыт прямо под открытым небом:P

Интерфейсы описывают... ИНТЕРФЕЙС. Они рассказывают, как вы можете взаимодействовать с классом, который его реализует.

Мне нравится аналогия с Legos: классы и экземпляры, колышки / отверстия сверху / снизу соответственно, а также размеры и формы, которые являются интерфейсами. Например, мне может понадобиться прямоугольный блок с колышками в сетке 2х4. Это те интерфейсы, которые меня интересуют, - интерфейс "мама" / "мама", а также интерфейс "прямоугольник". Они могут быть удовлетворены либо экземпляром прямоугольного блока Lego, либо другим экземпляром чего-то, "составленного" из двух половинных Legos, по 2 × 2 колышка в каждом, тем самым все еще придерживаясь указанного интерфейса. Поскольку все Legos имеют общий интерфейс (мужские и женские колышки), мы можем смешивать и комбинировать их, если это необходимо, независимо от того, происходит ли произведение из одного из этих новых наборов, где я могу построить гигантского муравья-робота, или это просто старый квадрат или прямоугольник., Лего, которое входит в гигантский чан, который вы использовали, чтобы вернуться в тот день. Черт, я даже могу смешивать официальные Legos с легендами бренда X, потому что "интерфейс" мужчина / женщина "привязан".

Программирование на интерфейсах позволяет нам смешивать и сочетать повторно используемые компоненты кода, как мы делаем Legos.

Другие вопросы по тегам