Как вы переходите от абстрактного описания проекта к реальному коду?

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

Но теперь профессор вбрасывает интерфейсы и абстрактные классы в микс. Интеллектуально, я могу узнать, как они работают, но я ухаживаю за моими ногами, выясняя, как использовать эти новые инструменты с текущим проектом (имитируя веб-сервер).

В моих профессорах собственные слова, отображение абстрактного описания в Java-код - настоящий трюк. Итак, какие шаги лучше всего использовать для перехода с английского (или любого другого) на компьютерный код? Как вы решаете, где и когда создавать интерфейс, или использовать абстрактный класс?

Ответ 1

Итак, какие шаги лучше всего использовать для перехода с английского (или на ваш язык) на компьютерный код?

Опыт - это то, чему вас учит, как это сделать. Если это еще не придет естественно (и не чувствую себя плохо, если это не так, потому что это занимает много времени!), Есть несколько вопросов, которые вы можете задать себе:

  • Каковы основные концепции системы? Как они связаны друг с другом? Если бы я описывал это кому-то еще, какие слова и фразы я использовал бы? Эти мысли помогут вам решить, какие классы полезны для размышлений.

  • Какие виды поведения имеют эти вещи? Существуют ли между ними естественные зависимости? (Например, LineItem не имеет значения или имеет смысл без контекста Order, а также не используется Engine без Car.) Как поведение влияет на состояние других объектов? Общаются ли они друг с другом, и если да, то каким образом? Эти мысли помогут вам разработать публичные интерфейсы ваших классов.

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

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

Нет жестких и быстрых рецептов; снова, опыт - лучший путеводитель здесь. Тем не менее, есть некоторые эмпирические правила, которые вы можете придерживаться:

  • Если несколько несвязанных или существенно разных типов объектов предоставляют одну и ту же функциональность, используйте интерфейс. Например, если интерфейс Steerable имеет метод Steer(Vector bearing), может быть много разных вещей, которые можно управлять: Boat s, Airplane s, CargoShip s, Car s и т.д., Это совершенно несвязанные вещи. Но все они имеют общий интерфейс, позволяющий управлять.

  • В общем, попробуйте использовать интерфейс вместо абстрактного базового класса. Таким образом, вы можете определить единую реализацию, которая реализует N интерфейсов. В случае Java у вас может быть только один абстрактный базовый класс, поэтому вы заблокированы в определенной иерархии наследования, как только вы скажете, что класс наследуется от другого.

  • Всякий раз, когда вам не нужна реализация из базового класса, определенно поддерживайте интерфейс над абстрактным базовым классом. Это также было бы удобно, если вы работаете на языке, где наследование не применяется. Например, в С# вы не можете наследовать struct из базового класса.

Ответ 2

В общем...

  • Читайте много кода других людей. Проекты с открытым исходным кодом отлично подходят для этого. Уважайте их лицензии.
  • Вы никогда не получите его совершенным. Это итеративный процесс. Не обескураживайте, если вы не понимаете это правильно.
  • Практика. Практика. Практика.
  • Исследования часто. Продолжайте решать все более сложные проекты/проекты. Даже если вокруг есть легкие.

Нет волшебной пули или алгоритма хорошего дизайна.

В настоящее время я вскакиваю с дизайном, который, как я считаю, порядочен и работает от этого.

Когда время будет правильным, я пойму, что результат будет реорганизован (переписан) раньше, чем позже.

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

Продолжайте делать это, и все будет хорошо.

Ответ 3

Что вы действительно должны сделать, это код сверху вниз, а не снизу вверх. Напишите свою основную функцию так четко и лаконично, как вы можете использовать API, которые вы еще не создали, как если бы они уже существовали. Затем вы можете реализовать эти API аналогичным образом, пока у вас не будет функций длиной всего несколько строк. Если вы кодируете снизу вверх, вы, вероятно, создадите целую кучу вещей, которые вам действительно не нужны.

С точки зрения создания интерфейса... в значительной степени все должно быть интерфейсом. Когда вы используете API, которые еще не существуют, предположите, что каждый конкретный класс является реализацией какого-либо интерфейса и использует объявленный тип, который указывает на этот интерфейс. Ваше наследование должно выполняться исключительно с интерфейсами. Создавайте конкретные классы в самом низу, когда вы предоставляете реализацию. Я бы предложил избегать абстрактных классов и просто использовать делегирование, хотя абстрактные классы также разумны, когда две разные реализации отличаются незначительно и имеют несколько функций, которые имеют общую реализацию. Например, если ваш интерфейс позволяет перебирать элементы, а также предоставляет функцию sum, функция sum тривиально реализуется с точки зрения функции итерации, поэтому это разумное использование абстрактного класса. Альтернативой было бы использовать шаблон декоратора в этом случае.

Вы также можете найти Google Techtalk " Как создать хороший API и почему это важно", чтобы быть полезным в этом отношении. Вам также может быть интересно прочитать некоторые мои собственные наблюдения за дизайном программного обеспечения.

Ответ 4

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