Прилагательные "стройная" и "зеленая" заменяем на прилагательные "фигурный" и "цветной", отводя им возможность быть уточненным - какая именно фигура и какой именно цвет.
Существительные "лес", "зима", "лето" относим к самостоятельным классам, образованным от базового класса TObject. Существительное "елочка" наследуем от базового класса TObject, от интерфейсов "фигурный" и "цветной", а также добавляем неименованные интерфейсы из отдельных глаголов "родиться" и "рости". Быть может, что при большем объеме исходного текста мы бы пришли к иной схеме классов и выделили бы эти неименованные интерфейсы явно.
Довольно интересным является вопрос о союзе "и". По исходному тексту, функция "быть" возвращает набор из существительных "зима" и "лето". Если отнести эти существительные к разным классам, то получим набор разнотипных данных. Это на мой взгляд некрасиво и лучше провести модификацию схемы классов. Проведем укрупнение классов "зима" и "лето" путем отнесения их к одному классу и различением их признаком "время года". Исходной иерархией является:
classТЗима : publicTObject {};
classTЛето : publicTObjct {};
Результирующей иерархией является укрупненная или агрегированная:
enum ЕВремяГода = { зима, лето};
class ТВремяГода : public TObject
{
public:
ЕВремяГода ВремяГода;
};
Если целевой язык программирования позволяет, то следует определиться со спецификатором константности аргументов, передаваемых по ссылке, и константности функций по признаку - изменяет функция состояние объекта или нет. Если функция не изменяет состояние объекта, то, очевидно, она может быть объявлена константной. Кстати, если в результате проектирования классов мы получим классы с только константными функциями, то смело можно сказать, что исходный текст содержал описание статического состояния объектов. Если же в иерархии полученных классов все функции только константные, то значит схема классов безжизненная. И после этого можно идти обратно к постановщику и громко вопрошать: "И???"
Шаг 5
На этом шаге, кстати, последнем, следует аккуратно, без помарок выписать схему классов на выбранном языке программирования. Здесь уже требуются только аккуратность и знание синтаксиса языка.
В нашем примере может получиться что-то типа:
#include ...
class TЛес : public TObject {};
enum ЕВремяГода { зима, лето};
class ТВремяГода : public TObject
{
public:
const ЕВремяГода GetВремяГода()
{ return ВремяГода};
{};
};
// здесь есть два варианта и второй в том, чтобы объявить
// время года как typedef ЕВремяГода ТВремяГода;
// какой вариант выбрать - дело вкуса.
// я выбрал первый потому, что он позволяет запретить
// изменение времени года для созданного объекта.
typedef vector <ТВремяГода> ВременаГода;
enum Фигура { никакая, стройная};
enum Цвет { никакой, зеленый};
class TФигурный
{
public:
// получение фигуры, зная времена года
const virtual Фигура Быть( ВременаГода& ) = 0;
// получение времени года, зная фигуру
const virtual ВременаГода Быть( Фигура) = 0;
};
class TЦветной
{
public:
// получение цвета, зная времена года
const virtual Цвет Быть( ВременаГода& ) = 0;
// получение времени года, зная Цвет
const virtual ВременаГода Быть( Цвет) = 0;
};
class ТЕлочка
: public TObject,
public ТФигурный,
public ТЦветной
{
public:
constvirtualФигура Быть( ВременаГода& );
const virtual ВременаГода Быть( Цвет);
const ТЛес Родиться();
const ТЛес Рости();
ТЕлочка(); // конструктор вызывается, когда елочка родится
~ТЕлочка();
// деструктор вызывается не тогда, когда елочку срубят,
// а тогда, когда после Нового Года выбросят на помойку
// и бедный дворник должен будет ее сжечь, поскольку
// елки в контейнеры грузить нельзя ;)
};
// получили две функции Быть с одинаковым аргументом.
// подобные проблемы следует решать по правилам применяемого
// языка. В нашем случае придется поменять
// имена функций на менее читабельные.
В примере я хотел сначала писать на Object Pascal. Мысленно разговаривая с читателем, услышал шум и топот ног и выкрики с мест - "А почему не С++?". Подумал и согласился - пусть будет на C++. Конечно же, приведенная метода не есть абсолют. Как говорится, если победишь в бою с нарушением устава - молодец, творчески мыслишь, отбрасывая устаревшие догмы. Если проиграл соблюдая устав - негодяй, который не смог постичь вековые истины. Если данная метода кому поможет - то-то я порадуюсь... Мне лично иногда помогает, особенно когда голова уже ничего не соображает и приходится действовать на автопилоте. Или когда приходится разбираться в исходниках и отгадывать - что же автор хотел сказать. Осуществлять своего рода модный ныне реинжиниринг. Что интересно, потом на свежую голову просмотришь что понаписал и удивляешься своей прозорливости и вообще тому, что это работает.