Здравствуйте, MozgC, Вы писали:
MC>Где ты там увидел пример про проблемы с классом String (как ты говоришь)?
Там пример про проблемы со всеми классами такого рода.
MC> Просто 2 предложения теории, к тому же к классу String не имеющей никакого отношения.
Я не виноват, что ты не в состоянии экстраполировать пример с одного класса на другой.
MC>Я задал несколько раз конкретный вопрос, попросил привести КОНКРЕТНЫЙ пример про проблемы с классом STRING, раз ты говоришь что он неправильно спроектирован.
Ну назови в примере топик пастера класс String, если тебя это смущает.
MC>Ты либо не читаешь вопрос,
Я уже раз пять ответил на вопрос, я не виноват, что тебе ответ не нравится.
MC>К сожалению, это ты так ведешь дискуссию.
Боюсь, что это ты ее так читаешь..
Здравствуйте, AndrewVK, Вы писали:
RO>>Кто-нибудь может доходчиво объяснить, зачем класть эти функции в еще один класс? Классы же нельзя расширять. AVK>А зачем расширять статические классы?
Чтобы положить еще функций для работы с тем классом.
RO>> Даже в .NET с ее extension methods, если я правильно понимаю, нельзя запихивать в объект статические члены. AVK>Что значит запихивать?
В .NET же можно сделать void SetHello(this String s) { s = "Hello"; }, и появится метод String.SetHello. А вот если у тебя есть ObjectHelper и ты хочешь, чтобы там появилась еще пара (статических) функций, то это даже с extension methods не выйдет (или я неправ?). Какой-то беспорядок получается: одни функции живут в Object, другие — в ObjectHelper, третьи — еще в каком-то классе.
В C++, например, это выглядело бы так:
// library codenamespace NS
{
class Object
{
SomeCollection getChildren();
};
size_t getFullSize(Object const &);
}
// user code
size_t getFullSizeInPetabytes(NS::Object const &);
// и здесь функции вызываются одинаково, компилятор сам их вытащит оттуда, откуда нужно:
NS::Object o;
getFullSize(o);
getFullSizeInPetabytes(o);
RO>>Так вот, что мешает просто сделать свободные функции? AVK>Отсутствие таковых в шарпе и джаве, к примеру.
А автор где-то указал язык программирования?
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, gandjustas, Вы писали:
G>>Формальность и объективность не одно и тоже. IB>Еще раз повторить? Оппонент утверждал, что его критерий формален — выяснилось, что ни разу. IB>Что здесь не объективного?
Необъективен сам критерий, независимо от формальности и неформальности.
G>>Одно другому не мешает. IB>И что ты хочешь этим сказать?
То что сама по себе цифирка ни о каком качестве кода не говорит.
G>>Не надо гнаться за удобством, но и жертвовать удобством в счет "правильности" тоже не лучшее решение. IB>В данном случае "правильность" не абстрактна и может быть выражена совершенно конкретными циферками, в чем легко убедиться опять-таки внимательно прочитав топик.
См выше.
G>>При эволюционном проектировани публичные контракты могут меняться достаточно часто. IB>Тогда наоборот, такой подход изумительно подходит для эволюционного проектирования, так как помимо всего прочего еще и компилятор следит за тем, что публичный контракт поменялся, а тот кто им пользуется — еще нет.
Только на мелкое исправление контракта получается много исправлений методов в разных классах.
Если методы находятся внутри класса, то исправления локальны.
Мелочь, а приятно.
G>>Этот тезис не противоречит вызовам A.B(x), менящюим x. IB>Ты любой код меняющий x помещаешь в x?
Метод, который принимает x в качестве параметра и его действия заключаются в измененении x, я помещу в класс x.
IB>UI например?
Что например?
IB>Надеюсь, все таки нет... Правильный вызов будет выглядет так: var newX = A.B(oldX);
А если нельзя объект копировать?
Здравствуйте, Roman Odaisky, Вы писали:
RO>>>Кто-нибудь может доходчиво объяснить, зачем класть эти функции в еще один класс? Классы же нельзя расширять. AVK>>А зачем расширять статические классы? RO>Чтобы положить еще функций для работы с тем классом.
Что значит положить? Дописать просто функцию в существующий исходник класса? Никаких проблем. Добавить функцию в рантайме? Какой смысл? Добавить функцию в скомпилированный уже класс? Такое невозможно ни с каким классом в подавляющем большинстве компилируемых языков.
AVK>>Что значит запихивать? RO>В .NET же можно сделать void SetHello(this String s) { s = "Hello"; }
Можно.
RO>, и появится метод String.SetHello.
Нет, не появится. Просто этот метод можно будет вызывать через точку от аргумента, не более того.
RO> А вот если у тебя есть ObjectHelper и ты хочешь, чтобы там появилась еще пара (статических) функций, то это даже с extension methods не выйдет
А зачем это нужно? Честно говоря, я впервые о таком пожелании слышу.
RO> Какой-то беспорядок получается: одни функции живут в Object, другие — в ObjectHelper, третьи — еще в каком-то классе.
Беспорядок, он исключительно в голове архитекта. Если там бардак, то и в коде бардак.
RO>В C++, например, это выглядело бы так: RO>[c] RO>// library code
RO>namespace NS RO>{ RO> class Object RO> { RO> SomeCollection getChildren(); RO> };
RO> size_t getFullSize(Object const &); RO>}
RO>// user code
RO>size_t getFullSizeInPetabytes(NS::Object const &);
RO>// и здесь функции вызываются одинаково, компилятор сам их вытащит оттуда, откуда нужно:
Перегрузка с extension methods тоже возможна, только не глобально по имени, а в контексте типа аргумента с учетом наследования и реализации интерфейсов. Если тебя интересуют конкретные правила, на основании которых производится выбор среди всех доступных методов экземпляра и extension methods — самым лучшим будет ознакомиться с соответствующей частью стандарта C#.
AVK>>Отсутствие таковых в шарпе и джаве, к примеру. RO>А автор где-то указал язык программирования?
Судя по pascal casing методов и статическим классам — с большой долей вероятности это все же C#.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, gandjustas, Вы писали:
G>Только на мелкое исправление контракта получается много исправлений методов в разных классах.
Контракт первичен. Если его надо править, значит его надо править в любом случае, вне зависимости от наличия хелперов.
IB>>UI например? G>Что например?
Ну, например нужно показать форму, в которой можно подредактировать некий класс А. оформлено это все ввиде функции, которой на вход передается единственный параметр с экземпляром редактируемого класса. Куда эту функцию помещаем?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, stump, Вы писали:
S>Здравствуйте, Ага, Вы писали:
Ага>>А теперь представь, появилось новое бизнес требование . TaxRate теперь не свойство продукта, а вычисляется в зависимости от клиента (страна/штат и т.д, физическое лицо/юридическое лицо, и т.д.). Теперь какой подход лучше? S>Нет, давай останемся в рамках первоначальных условий. Все мы понимаем, что изменение требований влечет изменение дизайна.
Это лишь пример, который показывает, что GetTotal и GetSubtotal, возможно, имеют такое же отношение к Customer и Country как и к Order. А следовательно не должны являться членами всех выше перечисленных сущностей.
Кроме того, если при изменении требований приходится серьезно изменять дизайн и переписывать половину существующего код ( а в данном случае так и будет), то это плохой дизайн.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Ага, Вы писали:
Ага>>А теперь представь, появилось новое бизнес требование . TaxRate теперь не свойство продукта, а вычисляется в зависимости от клиента (страна/штат и т.д, физическое лицо/юридическое лицо, и т.д.). Теперь какой подход лучше?
Z>Не аргумент. Они потребуют практически одинаковой работы по переделке дизайна. TaxRate станет внешним параметром.
А для меня аргумент. TaxRate и не был свойством продукта, как и GetTotal/GetSubtotal не были методами Order/OrderLine. Поэтому и понадобятся изменения в дизайне. Если бы эти обязанности изначально назначены правильным сущностям, то изменения не потребовались бы. Дизайн должен помогать реализовывать требования, а не мешать.
Здравствуйте, IB, Вы писали:
IB>Там пример про проблемы со всеми классами такого рода. IB>Я не виноват, что ты не в состоянии экстраполировать пример с одного класса на другой.
MC>>Я задал несколько раз конкретный вопрос, попросил привести КОНКРЕТНЫЙ пример про проблемы с классом STRING, раз ты говоришь что он неправильно спроектирован. IB>Ну назови в примере топик пастера класс String, если тебя это смущает.
Нафига мне его как-то называть?
И Причем тут экстраполировать, я тебе задал КОНКРЕТНЫЙ вопрос про КОНКРЕТНЫЕ проблемы с КОНКРЕТНЫМ классом. Раз не можешь дать конкретный ответ, то так и напиши что не хочешь, или не можешь, или что конкретно ты не встречал проблем с классом String. Ты не способен адекватно и конкретно ответить на вопрос? Если не способен, то не отвечай, это будет лучше чем отвечать не в тему.
Здравствуйте, Ага, Вы писали:
Ага>>>А теперь представь, появилось новое бизнес требование . TaxRate теперь не свойство продукта, а вычисляется в зависимости от клиента (страна/штат и т.д, физическое лицо/юридическое лицо, и т.д.). Теперь какой подход лучше?
Ага>А для меня аргумент. TaxRate и не был свойством продукта, как и GetTotal/GetSubtotal не были методами Order/OrderLine. Поэтому и понадобятся изменения в дизайне. Если бы эти обязанности изначально назначены правильным сущностям, то изменения не потребовались бы. Дизайн должен помогать реализовывать требования, а не мешать.
Надо как-то менее противоречиво формулировать мысли.
Здравствуйте, AndrewVK, Вы писали:
RO>> А вот если у тебя есть ObjectHelper и ты хочешь, чтобы там появилась еще пара (статических) функций, то это даже с extension methods не выйдет AVK>А зачем это нужно? Честно говоря, я впервые о таком пожелании слышу.
RO>> Какой-то беспорядок получается: одни функции живут в Object, другие — в ObjectHelper, третьи — еще в каком-то классе. AVK>Беспорядок, он исключительно в голове архитекта. Если там бардак, то и в коде бардак.
Ну представь себе. Ты используешь библиотеку, в ней есть класс Object и статический класс ObjectHelper со всякими внешними функциями для Object. Ты хочешь написать еще пару внешних функций для действий, которые тебе нужно выполнять над Object для решения своих задач. Куда ты их положишь? А если ты пишешь библиотеку, опирающуюся на Object/ObjectHelper, то ты будешь поставлять, кроме Object и ObjectHelper, еще и ObjectHelper2?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, gandjustas, Вы писали:
G>>Только на мелкое исправление контракта получается много исправлений методов в разных классах. AVK>Контракт первичен. Если его надо править, значит его надо править в любом случае, вне зависимости от наличия хелперов.
Это один из взглядов. На мой взгяд первичен функционал программы.
IB>>>UI например? G>>Что например?
AVK>Ну, например нужно показать форму, в которой можно подредактировать некий класс А. оформлено это все ввиде функции, которой на вход передается единственный параметр с экземпляром редактируемого класса. Куда эту функцию помещаем?
При функциональном проектировании не будет формы, которая редактирует какой-то объект. Да и куча других проблем есть у такой организации кода.
Здравствуйте, gandjustas, Вы писали:
G>>>Только на мелкое исправление контракта получается много исправлений методов в разных классах. AVK>>Контракт первичен. Если его надо править, значит его надо править в любом случае, вне зависимости от наличия хелперов. G>Это один из взглядов. На мой взгяд первичен функционал программы.
Контракт первичен по отношению к реализации. При чем тут функционал? Функционал не просто первичен, он определяет что нам нужно.
AVK>>Ну, например нужно показать форму, в которой можно подредактировать некий класс А. оформлено это все ввиде функции, которой на вход передается единственный параметр с экземпляром редактируемого класса. Куда эту функцию помещаем? G>При функциональном проектировании не будет формы, которая редактирует какой-то объект.
А что будет?
G> Да и куча других проблем есть у такой организации кода.
Какой такой?
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, Roman Odaisky, Вы писали:
RO>Ну представь себе. Ты используешь библиотеку, в ней есть класс Object и статический класс ObjectHelper со всякими внешними функциями для Object. Ты хочешь написать еще пару внешних функций для действий, которые тебе нужно выполнять над Object для решения своих задач. Куда ты их положишь?
В собственный хелпер с extension методами в отдельбном неймспейсе.
RO> А если ты пишешь библиотеку, опирающуюся на Object/ObjectHelper, то ты будешь поставлять, кроме Object и ObjectHelper, еще и ObjectHelper2?
Да, только не ObjectHelper2, а что нибудь более отражающее сущность моей библиотеки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1095 on Windows Vista 6.0.6001.65536>>
Здравствуйте, IB, Вы писали:
MC>>а AndrewVK, говорит что нельзя — "перфоманс уже не тот". IB>AVK говорит, что данный метод для своей корректной работы (например из соображений производительности), должен иметь доступ к приватным переменным класса => этот метод имеет полное право быть членом класса.
Иван, у тебя получается достаточно странная логика. С одной стороны высокоуровневые рассуждения о связности (я их не опровергаю, даже за) о том как важно разделять и властвовать, с другой стороны, когда речь дошла до практики, вдруг начинаются прыжки в сторону на тему "для эффективной реализации, метод должен быть членом класса".
У тебя получается некоторый String с методами, которые остались внутри просто потому что их нельзя выдернуть не просадив производительность (абсолютно нелепая выйдет компания) и помойка для всех остальных методов в хелпере. Мне это совсем не видится светлым будущим и, думаю, надо, всё же, чётко разделить теорию и практику. Раскидать методы по N классам достигнув абстрактной крутости и создав абсолютно нелогичный API не представляет мне достойной целью.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, stump, Вы писали:
S>>Написано "Class Coupling: 6" IB>Class Coupling — связь между классами.
S>>Написано: "In computer science, coupling IB>Просто Coupling — связность.
Остальную часть цитаты отрезал чтобы не мешала полемизировать и делать "правильные" выводы.
S>> О чем тут еще можно спорить? IB>Вот и я не понимаю, о чем: Написано же английским по белому " Low coupling refers to a relationship in which one module interacts with another module through a stable interface and does not need to be concerned with the other module's internal implementation" IB>Так вот interacts with another module through a stable interface — это и есть тот самый class coupling, который считает студия и в его большем количестве ничего плохого нет.
Как раз есть, это очень плохо. Полхо так же то что ты не можешь этого понят, зациклившись на ничем не подкрепленных правилах.
S>>Это ты ее объявил главной. IB>У нас разговор о простоте поддержки кода. Class Coupling на нее мало влияет, а вот Maintainability index имеет самое прямое и непосредственное отношение, он по сути это и меряет — простоту поддержки кода.
Class coupling сильно влияет на простоту поддержки. Цитата из MSDN :
Avoid excessive class coupling
TypeName
AvoidExcessiveClassCoupling
CheckId
CA1506
Category
Microsoft.Maintainability
Breaking Change
Breaking
Cause
A type or method is coupled with many other types.
Rule Description
This rule measures class coupling by counting the number of unique type references that a type or method contains.
Types and methods with a high degree of class coupling can be difficult to maintain. It is a good practice to have types and methods that exhibit low coupling and high cohesion.
How to Fix Violations
To fix this violation, try to redesign the type or method to reduce the number of types to which it is coupled.
When to Suppress Warnings
Exclude this warning when the type or method is still considered maintainable, despite its large number of dependencies on other types.
Избегайте чрезмерной связанности классов!
Высокая связанность классов (high degree of class coupling — подчаркиваю) делает затруднительной поддержку.
Хорошей практикой является создание типов демонстрирующих высокую кохессию (к кохессии мы еще вернемся) и низкую связность.
Так вот, использование "четкого принципа": "методы которые работают через публичный контракт класса должны быть вынесены за пределы этого класса", неизбежно и автоматически ведет к повышению class coupling и уменьшению кохессии.
Но в MSDN, к счастью сидят не столь твердолобые ребята, о чем свидетельствует последний абзац приведенной цитаты.
S>> Метрика "Maintainability Index" изменилась на 1 при значении 92, а метрика "Class Coupling" изменилась на 1 при значении 6. IB>Какая разница насколько изменилась метрика Class Coupling, если она не имеет никакого отношения к делу?
Оказывается имеет, прямое отношение см. выше. IB>Давай опять по новой. Если следовать твоей логике, то DI — увеличивает связность, так как при использовании DI увеличивается Class Coupling по метрикам студии.
Мы обсуждаем конкретные метрики конкретного кода, давай не будем "заводить рака за угол".
S>> Очевидно что изменение дизайна оказало наибольшее влияние на метрику "Class Coupling", IB>Проблема только в том, что эта метрика имеет весьма посредственное отношение к обсуждаемому вопросу.
Проблема в том что ты не можешь понять основных принципов анализа метрик кода, и меня это удивляет. Ты не видишь что показывают метрики. Их надо оценивать интегрально. И они показывают какие характеристики кода как измениолись. В данном случае метрики показали что введение хелпера практически ни на что не повлияло (не повлияло и на Maintainability Index) кроме связности классов, оно ее резко увеличило.
Можно провести дальнейший анализ, а почему Maintainability Index остался на месте когда class coupling полез вверх? Да потому что пример достаточно прост и переносимые методы очень элементарны.
Но. пример показал тенденцию. И ты этого не хочешь замечать, видимо по тому что эта тенденция тебе не нравится.
S>>Название метрики "Class Coupling" переводится как "связность классов". IB>Class Coupling меряет связи классов через публичный контракт, которые считаются "хорошими" с точки зрения связности.
Даже если онии хорошие, излишнее количество этих связей рано или поздно начнет создавать проблемы. S>> Просто данный анализ опровергает многие из твоих утверждений, IB>Он не опровергает, а как раз подтверждает. Очень хорошо подтверждает, надеюсь, объяснил почему? IB>Давай еще раз, если не понятно. По неизвестной мне причине, ты, под связностью, понимаешь число связей между классами, тогда как вся прогрессивная общественность (см википедию) понимает под этим число неявных связей. При этом считается, что перевод неявных связей в явные связность уменьшает — надеюсь не надо объяснять почему? (Для примера см DI, который как раз этим и занимается)
Ага теперь про твои любимые "неявные связи". Вся прогрессивная общественность называет это кохессией (зацеплением). И она тоже бывает хорошей и плохой:
Cohesion is a measure of how strongly-related or focused the responsibilities of a single class are. In object-oriented programming, if the methods that serve the given class tend to be similar in many aspects the class is said to have high cohesion. In a highly-cohesive system, code readability and the likelihood of reuse is increased, while complexity is kept manageable.
Сужествуют различные типы кохессии. Рассматриваемый нами тип (метод использует данные класса) можно отнести к комуникативной и частично функциональной кохессии
Communicational cohesion
Communicational cohesion is when parts of a module are grouped because they operate on the same data (e.g. a module which operates on the same record of information).
Functional cohesion (best)
Functional cohesion is when parts of a module are grouped because they all contribute to a single well-defined task of the module (e.g. parsing XML in the case of Expat (XML)).
...
communicational and sequential cohesion are very good; and functional cohesion is superior.
(все цитаты из википедии)
Т.е. размещение методов котоорые оперируют данными класса внутри самого класса имеет смысл и может дать положительный эффект. Сейчас ты скажешь "давай продолжим твою мысль и разместим все методы в одном классе". И все станет очень плохо:
Coincidental cohesion (worst)
Coincidental cohesion is when parts of a module are grouped arbitrarily (at random); the parts have no significant relationship (e.g. a module of frequently used mathematical functions).
(и то иногда приходится так поступать).
IB>Теперь давай разберем твой пример: Понятно, что связь между методом и классом есть всегда, явная она или не явная. Если метод внутри класса, то связь неявная, что выражается в меньшем числе метрики Class Coupling и меньшем Maintainability index-е, понятно, что поддерживать неявную связь сложнее чем явную. Как только мы вынесли метод наружу, увеличилось число явных связей (увеличилась метрика Class Coupling) и, как следствие, увеличилась метрика Maintainability index, говорящая о том, что такой код проще поддерживать.
Очень натянутые выводы, плохой анализ. Любой видит, что с выносом методов в хелпер Maintainability index увеличился на 1% и за это заплачено значительным увеличением class coupling.
Я к чему веду?
Я не утверждаю, что есть "четкий принцип" — "если метод использует публичный контракт класса — он должен быть размещен в данном классе."
Я не утверждаю, что есть "четкий принцип" — "если метод использует публичный контракт класса — он должен быть вынесен в другой класс."
Я утверждаю, что есть оба принципа, и применительно к конкретным условиям может быть предпочтителен один или другой. И в ходе дискуссии было рассмотрено немало кейсов для обоих.
А вот тупое (в смысле прямолинейное и бездумное) следование доному из них, ни к чему хорошему привести не может.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, gandjustas, Вы писали:
G>>>>Только на мелкое исправление контракта получается много исправлений методов в разных классах. AVK>>>Контракт первичен. Если его надо править, значит его надо править в любом случае, вне зависимости от наличия хелперов. G>>Это один из взглядов. На мой взгяд первичен функционал программы.
AVK>Контракт первичен по отношению к реализации. При чем тут функционал? Функционал не просто первичен, он определяет что нам нужно.
А то что нам нужно в итоге определяет контракты.
AVK>>>Ну, например нужно показать форму, в которой можно подредактировать некий класс А. оформлено это все ввиде функции, которой на вход передается единственный параметр с экземпляром редактируемого класса. Куда эту функцию помещаем? G>>При функциональном проектировании не будет формы, которая редактирует какой-то объект.
AVK>А что будет?
Что нибудь другое.
G>> Да и куча других проблем есть у такой организации кода. AVK>Какой такой?
Когда экранные формы привязываются к объектам.
Здравствуйте, Ага, Вы писали:
Ага>Это лишь пример, который показывает, что GetTotal и GetSubtotal, возможно, имеют такое же отношение к Customer и Country как и к Order. А следовательно не должны являться членами всех выше перечисленных сущностей.
Вообще-то сумма по заказу это свойство заказа, не зависимо от чего зависит расчет этой суммы, где расположен метод, который ее считает. и вообще считается она или хранится в где нибудь.
Есть такое понятие "предметная область программы". В предметной области сумма заказа есть всойство заказа. У многих программистов распространено мнение что дизайн программы может влиять на предметную область. Весьма печальное заблуждение, оно обычно приводит к несоответствию готовой программы функциональным требованиям.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, Ага, Вы писали:
Ага>>>>А теперь представь, появилось новое бизнес требование . TaxRate теперь не свойство продукта, а вычисляется в зависимости от клиента (страна/штат и т.д, физическое лицо/юридическое лицо, и т.д.). Теперь какой подход лучше?
Ага>>А для меня аргумент. TaxRate и не был свойством продукта, как и GetTotal/GetSubtotal не были методами Order/OrderLine. Поэтому и понадобятся изменения в дизайне. Если бы эти обязанности изначально назначены правильным сущностям, то изменения не потребовались бы. Дизайн должен помогать реализовывать требования, а не мешать.
Z>Надо как-то менее противоречиво формулировать мысли.
Что тут противоречивого? Была неверна построена модель предметной области, только и всего. Фраза "TaxRate теперь не свойство продукта" в бизнес требовании -- для облегчения понимания изменений.
Здравствуйте, stump, Вы писали:
S>Здравствуйте, Ага, Вы писали:
Ага>>Это лишь пример, который показывает, что GetTotal и GetSubtotal, возможно, имеют такое же отношение к Customer и Country как и к Order. А следовательно не должны являться членами всех выше перечисленных сущностей.
S>Вообще-то сумма по заказу это свойство заказа, не зависимо от чего зависит расчет этой суммы, где расположен метод, который ее считает. и вообще считается она или хранится в где нибудь.
В предметной области -- да, но это не означает, что класс заказа должен ее вычислять и/или хранить. Об этом и речь.
S>Есть такое понятие "предметная область программы". В предметной области сумма заказа есть всойство заказа. У многих программистов распространено мнение что дизайн программы может влиять на предметную область. Весьма печальное заблуждение, оно обычно приводит к несоответствию готовой программы функциональным требованиям.
А это к чему?