Павел Вишин: не вижу никакой толстоты. Это действительно отличное начало для программирования в целом, сам именно так и начинал. Но вопрос был именно про веб-разработку, писать на C для веба достаточно затратно, как вы знаете.
Про целостность я конечно лишнего тут хватанул, признаю. Но согласованность — вот что действительно меня интересует. А точнее — проверка работоспособности механизма ее обеспечения при одновременном обслуживании нескольких клиентских запросов. Собственно, решение уже найдено — JMeter позволил смоделировать различных (по поведению) клиентов и варьировать кол-во таких клиентов от теста к тесту.
Абсолютное сходство интерфейса в Generalization звучит убедительно, а главное очень хочется в это верить. Но напрягает момент, что зачастую в классах-наследниках появляются публичные методы, которых не было у родителя, а в коде можно встретить понижающее приведение типа (downcasting).
Implementation как декомпозиция объекта на составляющие мне тоже нравится. Только не понял, почему у тебя implementation в UML конфликтует с implementation в программировании. Если судить по синтаксису, например, Java или PHP, то для того, чтобы показать, что класс реализует интерфейс, используется именно ключевое слово implement. Один класс в свою очередь может реализовывать множество интерфейсов (например, IComparable, IMovable и IDrawable). Получается, что такой класс — это объединение решения нескольких задач внутри одного класса, интерфейс которого состоит из совокупности всех интерфейсов, им реализуемых ResultingClassInterface = {IComparable, IMovable, IDrawable}. В таком случае, если теперь двигаться в обратном направлении, рассматривая класс, как единое целое и затем выделяя из него подзадачи с вынесением их в отдельный интерфейс — это и получится декомпозиция.
В мануале IBM по UML про связь implementation написано следующее: The implementation relationship specifies that the realizing classifier must conform to the contract that the provided interface specifies. Это выполняется by design во всех языках программирования, поддерживающих интерфейсы в таком виде, как они понимаются например в Java, PHP или C#.
В том же самом мануале про связь realizationнаписано вот что: You can model the following situations using realization relationships:
A component is realized by a set of classifiers that provide its implementation. Вот это уже действительно похоже на то, что класс предоставляет своим клиентам абстракцию, складывающуюся из сервисов классов, с которыми он находится в отношении realization плюс возможно его собственные публичные методы. При этом не гарантируется, что новый класс будет на 100 % повторять интерфейсы классов, чью реализацию он представляет. Следовательно, никто не запрещает нам realization провернуть за счет делегирования и обойтись вовсе без наследования в этом случае. При этом внешний вид связи (пунктирная линия с пустым треугольником на конце) ничем не отличается от вида связи implementation и напоминает связь generalization, что меня вводит в заблуждение. Делегирование же в свою очередь обычно на диаграммах представляется связью association (собирательно название для agregation или composition). Рискну предположить, что связь realization должна использоваться вместо association при делегировании, когда ВСЕ методы класса, входящего в связь с одной стороны (service provider), имеют свое отражение в публичных методах класса на другой стороне связи (т.е. отношение между методами биективное).
Ну и пока не ясен для меня вопрос, как следует поступать, когда в приложении существует множество разношерстных по своему назначению классов + один интерфейс, который большинство из них (но не все!) должны реализовывать. Причем реализация эта в 99% случаев должна быть по умолчанию одинакова. Писать в каждом из классов реализацию — ад. Отнаследовать все эти класса системы от базового класс MyObject implements IInterface, в котором будет представлена реализация интерфейса по умолчания (а-ля C# или Java) — вроде перебор. И как при этом должна выглядеть диаграмма классов UML?
Вот как раз сижу и думаю над этим вопросом =) С одной стороны некорректных данных на этом участке уже быть не должно. С другой стороны поставщика данных для этого сеттера пишу не я… А если будут исключения, то проще будет найти жучка, если вдруг начнут валиться некорректные данные.
Спасибо! Пользовательским вводом тут и не пахнет, пример приведен из реальной жизни, метод используется на большой глубине чуть ли не в самом сердце боевой системы. Но вопрос-то был о сеттерах вообще, так что Ваши разъяснения оказались очень кстати.
email здесь приведен в качестве примера, возможно и не самого удачного. Нельзя же в коде на каждый вид используемой информации заводить по отдельному классу. Так дело может дойти до того, что будем проверять у целочисленных отсутствие дробной части, заведя класс TrueInteger.