Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обсуждение шаблонов проектирования (стереотипы), связь между кодом C++ и проектированием 
:(
    Опции темы
mes
Дата 18.6.2009, 20:11 (ссылка)  | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(zim22 @  18.6.2009,  18:46 Найти цитируемый пост)
интересно проследить, как рекомендация стала правилом:

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



--------------------
PM MAIL WWW   Вверх
atomicxp
  Дата 18.6.2009, 20:54 (ссылка)  | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Цитата(mes @  18.6.2009,  20:11 Найти цитируемый пост)
Кроме того рекомендация была переврана, и  дата-члены превратились в сущности (в контексте высказывания  также методы)

На самом деле поля не нужно группировать по этому правилу, если только не объявить их открытыми, о чём было сказано при обсуждении контейнеров свойств, потому что контейнер будет засчитываться за одно понятие. К тому же в данном случае всё это так же относится и к пространствам имён, которые тоже могут быть вложены одни в другие.

Кто-то может сказать, что это всё соблюдать при проектировании программ не нужно, но так же можно утверждать, что ООП бесполезен и использовать вместо него что угодно. Самой программе без разницы, что о ней думают её создатели, она просто выполняется. Эти правила нужны лишь программистам, чтобы писать более эффективные и надёжные программы.
PM MAIL WWW Skype GTalk Jabber   Вверх
mes
Дата 18.6.2009, 21:16 (ссылка)  | (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(atomicxp @  18.6.2009,  19:54 Найти цитируемый пост)
На самом деле поля не нужно группировать по этому правилу, если только не объявить их открытыми, о чём было сказано при обсуждении контейнеров свойств, потому что контейнер будет засчитываться за одно понятие.

без комментов  smile (чтоб опять не подумали , что я придираюсь)

Цитата(atomicxp @  18.6.2009,  19:54 Найти цитируемый пост)
Кто-то может сказать, что это всё соблюдать при проектировании программ не нужно,

Если это намек в мою сторону, то я говорил, что не надо фанатизма, а нужно подходить ко всему с головой.

Цитата(atomicxp @  18.6.2009,  19:54 Найти цитируемый пост)
что ООП бесполезен и использовать вместо него что угодно.

1. ООП не бесполезен, но он же и не всемогущ,
2. Cpp больше, чем ООП   smile 

Цитата(atomicxp @  18.6.2009,  19:54 Найти цитируемый пост)
Самой программе без разницы, что о ней думают её создатели, она просто выполняется

Вы забыли еще об одной стороне. Программе требуется развитие и сопровождение - и в этом вопросе ей не все равно smile
(программы одноневки не рассматриваются по вполне понятным причинам)
smile
Цитата(atomicxp @  18.6.2009,  19:54 Найти цитируемый пост)
Эти правила нужны лишь программистам, чтобы писать более эффективные и надёжные программы. 

Ваше "правило" о семи сущностях к этому не относится. Это такое же, как "правило похудания" не покупать еды, больше чем на N(не помню число) рублей в день.
smile


Это сообщение отредактировал(а) mes - 18.6.2009, 21:35


--------------------
PM MAIL WWW   Вверх
Леопольд
Дата 18.6.2009, 22:31 (ссылка) |   (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Вот есть у на автомобиль. А еще у нас есть кондиционер. Всё, раз так, то нельзя совмещать кондиционер и автомобиль потому что они разные... А автомобиль в кондиционере, это же вообще смешно! smile

Что мешает смешивать техники с успехом? Нельзя зацикливаться на чём-то одном. Это не путь к успеху. Надо уметь мыслить гибко. Для пущей эффективности, стоит изучить "велосипеды", что бы не изобрести в результате своих усиленных размышлений самокат smile А вот что получится после изучения велосипедов: автомобиль на трёх колёсах или электровеник, это зависит уже от тебя самого. А уж если получился автомобиль, да ещё и с гудком, то можно попытаться довести его до ума и получить через n лет спортивный болид.

Я ещё не слишком отступил от основной темы? smile

Даже рассуждая так примитивно, можно прийти к выводу что ограничивая себя только лишь одной технологией (живой пример бензиновые двигатели) развитие достигает своего потолка. Дальше можно пройти только изобретая что-то новое. Языки программирования и способы проектриования превратились в отдельную, пока ещё не признанную науку. Но это не значит что на них не распространяется это общее правило. ООП не аскиома в проектирование. Технология весьма полезная, но не единственная... Способы проектированя с использованием ООП весьма интересны и эффективны. Но не надо пытаться заменить процедурную часть программы на объектную (алгоритмы STL, например) только лишь потому что C++ поддерживает такую абстракцию синтаксически. Напомоню что это далеко не все его возможности. Это как ездить на автомобиле с кондиционером но вместо него, в жару, открывать люк на крыше (формой, подозрительно, напоминающий автомобиль), причём выпиленный своими руками на прошлой неделе.

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

Это сообщение отредактировал(а) Леопольд - 18.6.2009, 22:34


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
atomicxp
  Дата 20.6.2009, 02:21 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Шаблоны бесполезны в отрыве от их сферы применения. Можно пытаться определить, какой из них используешь постфактум, но это принесёт гораздо меньше пользы, и уж точно не поможет в проектировании, а только в исправлении реализации и приведения её к эталонному виду. Значит если описывать шаблоны по порядку, то это ничего не даст. В таком случае неверное придётся вначале объявить заголовочный файл, а детали реализации оставить на потом.

Шаблоны проектирования

Основные шаблоны (Fundamental)

    * Delegation/Делегирование (перепоручение): Передача ответственности за выполнение связанному объекту
    * Encapsulation or Information hiding/Инкапсуляция или Сокрытие данных: Предоставляет косвенные методы манипулирования данными объекта или класса, вместо манипуляции напрямую
    * Event Channel/Канал событий: Производит, выявляет, использует и реагирует на события.
    * Exceptions/Исключения: Поддерживает языковой механизм исключений
    * Functional design/Функциональный дизайн: Каждый класс программы имеет только одну функциональность
    * Immutable/Неизменяемый: Объект, который нельзя изменить после его создания
    * Inheritance or subclassing: Наследует методы от родительского класса для повторного использования кода
    * Interface/Интерфейс: Обеспечивает доступ к методам других классов
    * Marker interface: Позволяет получить информацию об объектах во времени исполнения
    * Property Container: Посредник между полями и методами класса


Порождающие шаблоны проектирования

    * Abstract Factory/Абстрактная фабрика, Kit (GoF): Позволяет изменять поведение системы, варьируя создаваемые объекты, при этом сохраняя интерфейсы
    * Anonymous subroutine objects:
    * Builder/Строитель (GoF): Отделяет конструирование сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться разные представления
    * Creator/Создатель экземпляров класса (GRASP): Решает кто должен создавать объект
    * Factory Method/Фабричный метод, Virtual Constructor/Виртуальный конструктор (GoF): Предоставляет подклассам интерфейс для создания экземпляров некоторого класса
    * Lazy initialization/Отложенная инициализация: Ресурсоёмкая операция выполняется только непосредственно перед тем, как будет использован её результат
    * Multiton/Мультитон: Гарантирует, что класс имеет поименованные экземпляры объекта и обеспечивает глобальную точку доступа к ним
    * Object Pool/Объектный пул: Использование заранее инициализированных объектов
    * Prototype/Прототип (GoF): Задаёт виды создаваемых объектов с помощью экземпляра-прототипа и создаёт новые объекты путём копирования этого прототипа
    * Resource acquisition is initialization: Гарантирует, что ресурсы высвобождаются при освобождении объектов использующих их
    * Singleton/Одиночка (GoF): Гарантирует, что у класса одновременно может быть только один экземпляр объекта и обеспечивает глобальную точку доступа к нему

Структурные шаблоны классов/объектов (Structural)

    * Adapter/Адаптер, Wrapper (GoF): Организует использования функций объекта, недоступного для модификации, через специально созданный интерфейс
    * Bridge/Мост, Handle/Описатель, Body/Тело (GoF): Разделяет абстракцию и реализацию так, чтобы они могли изменяться независимо
    * Composite/Компоновщик (GoF): Объединяет объекты в древовидную структуру для представления иерархии от частного к целому
    * Container
    * Decorator/Декоратор, Wrapper/Оболочка (GoF): Предназначен для динамического подключения дополнительного поведения к объекту
    * Extensibility
    * Information Expert/Информационный эксперт (GRASP): Обязанности должны быть назначены объекту, который владеет максимумом необходимой информации для её выполнения
    * Facade/Фасад (GoF): Позволяет скрыть сложность системы путем сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы
    * Flyweight/Приспособленец (GoF): Используется для уменьшения затрат при работе с большим количеством мелких объектов
    * Low Coupling/Низкая связанность (GRASP): Малое число зависимостей между классами, высокая степень повторного использования подсистем
    * Pipes and filters
    * Private class data
    * Protected Variations/Сокрытие реализации (устойчивый к изменениям) (GRASP): Защищает элементы от изменения других элементов (объектов или подсистем) с помощью вынесения взаимодействия в фиксированный интерфейс
    * Proxy/Заместитель, Surrogate (Суррогат) (GoF): Предоставляет объект, контролирующий доступ, перехватывая все вызовы к нему

Поведенческие шаблоны классов/объектов (Behavioral)

    * Blackboard: Обобщённый наблюдатель позволяющий множество считывающих и записывающих
    * Chain of Responsibility/Цепочка ответственности (GoF): Предназначен для организации в системе уровней ответственности
    * Command/Команда, Action/Действие, Transaction/Транзакция (GoF): Заключает в себе действие и его параметры.
    * Controller/Контроллер (GRASP): Берёт на себя ответственность за выполнение операций, приходящих от пользователя
    * Don't talk to strangers/Не разговаривайте с неизвестными (GRASP)
    * High Cohesion/Высокое зацепление (GRASP): Cильное сцепления внутри подсистем классов
    * Indirection/Перенаправление (GRASP): Поддерживает слабую связанность и возможность повторного использования путём назначения обязанностей посредника между ними промежуточному объекту
    * Interpreter/Интерпретатор (GoF): Представляет грамматику языка и интерпретацию
    * Iterator/Итератор, Cursor (GoF): Позволяет последовательный доступ к элементам объекта-агрегата без использования описаний каждого из объектов, входящий в состав агрегации
    * Mediator/Посредник (GoF): Помогает организовать взаимодействие систем, имеющих дело с разнородными источниками данных
    * Memento/Хранитель, Token (GoF): Не нарушая инкапсуляцию сохраняет во вне состояние объекта для его последующего восстановления
    * Null Object/Нулевой объект: Сбрасывает значение по умолчанию в ноль
    * Observer/Наблюдатель, Dependents, Publish-Subscribe, Event listener (GoF): Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии
    * Polymorphism/Полиморфизм (GRASP): Позволяет обрабатывать альтернативные варианты поведения на основе типа и заменять подключаемые компоненты системы
    * Pure Fabrication/Чистая выдумка (искусственный) (GRASP): Не отражающий никакого реального объекта предметной области, но специально придуманный для усиления связности, ослабления связанности или увеличения степени повторного использования
    * Restorer/Восстановитель: Альтернатива шаблону хранителю
    * Simple Policy
    * Specification: Перекомбинирует бизнес логику в булевы образы
    * State/Состояние, Objects for States (GoF): Используется в тех случаях, когда во время выполнения программы объект должен менять свое поведение в зависимости от своего состояния
    * Strategy/Стратегия (GoF): Предназначен для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости
    * Template Method/Шаблонный метод (GoF)
    * Visitor/Посетитель, Single-serving visitor, Hierarchical visitor (GoF)

Шаблоны параллельного программирования (Concurrency)

    * Active Object/Активный объект: Отделяет методы исполнения от ссылочных методов, которые находятся в их собственных потоках управления
    * Balking: Программный шаблон проектирования, который исполняет действия над объектами, только когда они находятся в особенном состоянии
    * Binding Properties/Связанные свойства: Сочетает множество наблюдателей влияющих на свойства различных объектов, для синхронизации или координирования в некотором направлении
    * Double checked locking: Предназначен для снижения накладных расходов на первое тестирование блокировки в небезопасной манере
    * Event-Based Asynchronous: Базируется на событиях адресов проблем с асинхронным шаблоном происходящим в многопоточных программах
    * Guarded suspension/Охраняемая приостановка: Управляет операциями, которые требуют и приобретённой блокировки, и удовлетворяющего предусловия до их исполнения
    * Half-Sync/Half-Async
    * Leaders/followers
    * Lock/Блокировка: Один поток ставит блокировку на ресурс предотвращая доступ или изменение с других потоков
    * Monitor Object/Объектный монитор:Подход к синхронизации двух или более компьютерных задач, которые используют общие ресурсы, обычно аппаратные устройства или наборы переменных
    * Reactor: Используется для обработки служебных запросов доставленных параллельно обработчикам служб в один или более входов
    * Read write lock: Допускает одновременный доступ на чтение к объекту, но требует монопольный доступ на операции записи
    * Scheduler/Планировщик: Используется для явного управления, когда потоки могут исполнять однопотоковый код
    * Thread pool/Пул потоков: Некоторое количество созданных потоков для выполнения ряда задач, которые обычно организованы в очереди
    * Thread-Specific Storage: Представляет программный метод, который использует статичную или глобальную память в локальном потоке
    * Single Thread Execution

MVC

    * Model-View-Controller/Модель-представление-контроллер
    * Model-View-Presenter
    * Presentation-Abstraction-Control

Enterprise

    * Business Delegate: Прячет сложности поиска и создания бизнес-сервисов
    * Composite Entity/Составная Сущность: Обеспечивает обмен данными между слоями, уменьшая сетевой трафик
    * Composite View: Созданёт составное визуальное представление
    * Data Access Objec(DAO)/Объект Доступа к Данным: Абстрагирует источник данных; обеспечивает прозрачный доступ к данным
    * Dispatcher View: Описывает особую комбинацию контроллера и диспетчера с видами и хелперами
    * Front Controller: Комбинирует Dispatcher, Front Controller и View Helper, откладывая обработку сигналов.
    * Intercepting Filter: Обеспечивает централизованную точку входа для управления обработкой запроса
    * Service Activator: Обеспечивает асинхронную обработку для компонентов EJB
    * Service Locator/Локатор Службы: Управляет исполнением запросов, кэшированием результатов и их обработкой
    * Service to Worker:  Описывает особую комбинацию контроллера и диспетчера с видами и хелперами
    * Session Facade/Фасад Сессии: Разделяет презентационный и сервисный уровни, обеспечивает интерфейсы фасада и посредника для сервисов
    * Transfer Object Assembler(Value Object Assembler): Прячет сложность бизнес-объекта, централизует обработку workflow
    * Transfer Object(Value Object)/Объект Перемещения: Прячет сложность бизнес-объекта, централизует обработку workflow
    * Value List Handler/Обработчик Списка Значений: Собирает составной Value Object из многих источников данных
    * View Helper: Обеспечивает предварительную и пост-обработку запроса

Архитектурные структурные шаблоны

    * Repository/Хранилище
    * Client/Server/Клиент/сервер
    * Domain Model/Модель предметной области, Data Mapper/Модуль таблицы
    * Layers/Многоуровневая система (абстрактная машина)
    * Data Streams/Потоки данных (конвейер или фильтр)

Архитектурные шаблоны централизованного управления

    * Вызов - возврат (сценарий транзакции - частный случай)
    * Диспетчер

Архитектурные шаблоны событийного управления

    * Передача сообщений
    * Управляемый прерываниями

Архитектурные шаблоны взаимодействие с базой данных

    * Active Record/Активная запись
    * Unit Of Work/Единица работы
    * Lazy Load/Загрузка по требованию
    * Identity Map/Коллекция обьектов
    * Record Set/Множество записей
    * Single Table Inheritance/Наследование с одной таблицей
    * Class Table Inheritance/Наследование с таблицами для каждого класса
    * Optimistic Offline Lock/Оптимистическая автономная блокировка
    * Отображение с помощью внешних ключей
    * Association Table Mapping/Отображение с помощью таблицы ассоциаций
    * Pessimistic Offline Lock/Пессимистическая автономная блокировка
    * Identity Field/Поле идентификации
    * Data Mapper/Преобразователь данных
    * Client Session State/Cохранение сеанса на стороне клиента
    * Server Session State/Cохранение сеанса на стороне сервера
    * Row Data Gateway/Шлюз записи данных
    * Table Data Gateway/Шлюз таблицы данных

Структурные шаблоны интеграции информационных систем

    * Взаимодействие "точка - точка"
    * Взаимодействие "звезда" (интегрирующая среда)
    * Смешанный способ взаимодействия

Шаблоны интеграции информационных систем по методу

    * Data-Centric/Интеграция систем по данным
    * Function-Centric/Функционально-центрический подход
    * Object-Centric/Объектно-центрический подход
    * Concept-Centric/Понятийно-центрический подход

Шаблоны интеграции информационных систем по типу обмена данными

    * Файловый обмен
    * Общая база данных
    * Удаленный вызов процедур
    * Обмен сообщениями

Антишаблоны проектирования

Управление разработкой ПО

    * Smoke and mirrors/Дым и зеркала: Демонстрация того, как будут выглядеть ненаписанные функции (название происходит от двух излюбленных способов, которыми фокусники скрывают свои секреты).
    * Software bloat/Раздувание ПО: Разрешение последующим версиям системы требовать всё больше и больше ресурсов.
    * Options checkbox/Функции для галочки: Превращение программы в конгломерат плохо реализованных и не связанных между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть).

Разработка ПО

    * Abstraction inversion/Инверсия абстракции: Создание простых конструкций поверх сложных (спорный)
    * Ambiguous viewpoint/Неопределённая точка зрения: Представление модели без спецификации её точки рассмотрения
    * Big ball of mud/Большой комок грязи: Система с нераспознаваемой структурой
    * Blob/Блоб, God object/Божественный объект: Объект, который хранит в себе слишком много, или делает слишком много
    * Gas factory/Бензиновая фабрика: Необязательная сложность дизайна
    * Input kludge/Затычка на ввод данных: Забывчивость в спецификации и выполнении поддержки возможного неверного ввода
    * Interface bloat/Раздувание интерфейса: Изготовление интерфейса очень мощным и очень трудным для осуществления
    * Magic pushbutton/Магическая кнопка: Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса.
    * Re-Coupling/Перестыковка: Процесс внедрения ненужной зависимости
    * Stovepipe system/Дымоход: Редко поддерживаемая сборка плохосвязанных компонентов
    * Race hazard(Race condition)/Гонки: Ошибка в определении последовательности различных порядков событий

Объектно-ориентированное программирование

    * BaseBean/Базовый класс-утилита: Наследование функциональности из класса-утилиты вместо делегирования к нему
    * CallSuper/Вызов предка: Для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы класса-предка.
    * Empty subclass failure/Ошибка пустого подкласса: Создание класса (Perl), который не проходит «проверку пустоты подкласса» («Empty Subclass Test») из-за различного поведения по сравнению с классом, который наследуется от него без изменений
    * God object/Божественный объект: Концентрация слишком большого количества функций в одиночной части дизайна (классе)
    * Object cesspool/Объектная клоака: Переиспользование объектов, чьё состояние не удовлетворяет (возможно неявному) контракту переиспользования.
    * Poltergeist/Полтергейст: Объекты, чьё единственное предназначение — передавать информацию другим объектам
    * Yo-yo problem/Проблема йо-йо: Структура (например: наследования) которая тяжело понятна вследствие избыточной фрагментации
    * Singletonitis/Синглетонизм: Избыточное использование паттерна синглетон

Программирование

    * Accidental complexity/Ненужная сложность: Внесение ненужной сложности в решение
    * Action at a distance/Действие на расстоянии: Неожиданное взаимодействие между широко разделёнными частями системы
    * Accumulate and fire/Накопить и запустить: Установка параметров подпрограмм в наборе глобальных переменных
    * Blind faith/Слепая вера: Недостаточная проверка (a) корректности исправления ошибки или (b) результата работы подпрограммы
    * Boat anchor/Лодочный якорь: Сохранение более не используемой части системы
    * Busy spin/Активное ожидание: Потребление ресурсов ЦПУ (процессорного времени) во время ожидания события, обычно при помощи постоянно повторяемой проверки, вместо того, чтобы использовать систему сообщений
    * Caching failure/Кэширование ошибки: Забывать сбросить флаг ошибки после её обработки
    * Checking type instead of membership(Checking type instead of interface)/Проверка типа вместо интерфейса: Проверка того, что объект имеет специфический тип в то время, когда требуется только определённый интерфейс
    * Code momentum/Инерция кода: Сверхограничение части системы путём постоянного подразумевания её поведения в других частях системы
    * Coding by exception/Кодирование путём исключения: Добавление нового кода для поддержки каждого специального распознанного случая
    * Cryptic code/Таинственный код: Использование аббревиатур вместо полных (самоописывающих) имён
    * Hard code/Жёсткое кодирование: Внедрение предположений об окружении системы в слишком большом количестве точек её реализации
    * Soft code/Мягкое кодирование: Патологическая боязнь жёсткого кодирования, приводящая к тому, что настраивается всё что угодно, при этом конфигурирование системы само по себе превращается в программирование.
    * Lava flow/Поток лавы: Сохранение нежелательного (излишнего или низкокачественного) кода по причине того, что его удаление слишком дорого или будет иметь непредсказуемые последствия
    * Magic numbers/Магические числа: Включение чисел в алгоритмы без объяснений
    * Procedural code/Процедурный код: Когда другая парадигма является более подходящей
    * Spaghetti code/Спагетти-код: Системы, чья структура редко понятна, особенно потому что структура кода используется неправильно
    * Soap bubble/Мыльный пузырь: Класс, инициализированый мусором, максимально долго притворяется, что содержит какие-то данные.

Методологические анти-паттерны

    * Copy and paste programming/Программирование методом копирования-вставки (китайский код): Копирование (и лёгкая модификация) существующего кода вместо создания общих решений
    * De-Factoring/Дефакторинг: Процесс уничтожения функциональности и замены её документацией
    * Golden hammer/Золотой молоток: Сильная уверенность в том, что любимое решение универсально применимо. Название происходит от английской поговорки «когда в руках молоток, все проблемы кажутся гвоздями».
    * Improbability factor/Фактор невероятности: Предположение о невозможности того, что сработает известная ошибка
    * Premature optimization/Преждевременная оптимизация: Оптимизация на основе недостаточной информации
    * Reinventing the wheel/Изобретение колеса: Ошибка адаптации существующего решения
    * Reinventing the square wheel/Изобретение квадратного колеса: Создание плохого решения, когда существует хорошее

Управление конфигурацией

    * Dependency hell/Ад зависимостей: Проблемы с версиями требующихся продуктов, особенно в системах UNIX/GNU/Linux
    * DLL hell/DLL-ад: Проблемы с версиями, доступностью и увеличением количества DLL, особенно в Microsoft Windows.

Некоторые организационные анти-паттерны

    * Analysis paralysis/Аналитический паралич: Выделение непропорционально больших усилий в фазе анализа проекта
    * Cash cow/Дойная корова: Закрытый продукт, приносящий выгоду, часто ведёт к самоуспокоенности относительно новых продуктов
    * Continuous obsolescence/Продолжительное устаревание: Выделение непропорционально больших усилий портированию системы в новые окружения
    * Cost migration/Сваливание расходов: Перенос расходов на проект к уязвимому отделу или бизнес-партнёру
    * Creeping featurism/Ползущий улучшизм: Добавление новых улучшений в ущерб качеству системы
    * Design by committee/Разработка комитетом: Результат того, что имеется много содействующих разработке, но не имеется единого видения
    * Escalation of commitment/Эскалация обязательств: Продолжение реализации решения в том случае, когда неправильность его доказана.
    * I told you so/Я тебе это говорил: Когда игнорируется предупреждение эксперта, являющееся оправданным
    * Management by numbers/Управление числами: Уделение избыточного внимания численным критериям управления, когда они неважны или стоимость их получения слишком высока
    * Management by perkele/Драконовские меры: Военный стиль управления без толерантности к диссидентству
    * Mushroom management/Управление грибами: Удержание работников в неинформированном и занятом состоянии
    * Scope creep/Расползание рамок: Дозволение рамкам проекта расти без должного контроля
    * Vendor lock-in/Замкнутость на продавце: Изготовление системы, избыточно зависящей от внешнего поставляемого компонента
    * Warm body/Тёплое тело: Человек, чей вклад в проект под сомнением, особенно если рассмотрен в панике
    * Single head of knowledge/Единственный знающий человек: ЕЗЧ (SHOK) применим в том случае, когда единственная личность во всей организации контролирует жизненно-важную область ноу-хау или информации о внутренностях системы.
    * Knight in shining armor/Рыцарь на белом коне: РНБК (KISA) происходит тогда, когда личность, которая не совершает ошибок, появляется на сцене и пытается починить всё, без сообщений о том, какие изменения он/она сделал/сделает и почему.

Социальные взаимотношения

    * Censorship/Цензура: Подавление дискуссии для предотвращения политического, социального и научного прогресса
    * Concentrated power(Political corruption)/Концентрация власти: Индивидуальное злоупотребление властью, даже с изначально хорошими помыслами
    * Democracy/Демократия: Большая группа индивидов не может принимать аргументированные решения, а руководствуется лишь поверхностной информацией.
    * Dictatorship/Диктатура: Ни один индивид не имеет всех умений необходимых для управления; также власть развращает
    * Discrimination/Дискриминация: Концентрация на неуместных особенностях усиливает экономическую неэффективность и социальную напряжённость
    * Dogmatic religion/Догма: Догма подавляет индивидуальное мышление и тормозит прогресс
    * Intolerance/Нетерпимость: Настаивание на изменении нежелательных-но-безопасных особенностей других людей влечёт усиление напряжённости и также является бесконечной задачей
    * Monopoly/Монополия: Без соперничества большинство эффектов свободного рынка не работают, и частная компания не имеет стимула действовать честно
    * Plurality voting system/Система голосования на основе большинства: Политика при голосовании на основе большинства вырождается в две полярно-противоположные партии, результатом чего является подавление других политических воззрений
    * Popularity contest/Соревнование в популярности: Популярность становится самодостаточной величиной и не сопоставима ни с каким другими параметрами или достоинствами
    * Racial segregation/Сегрегация: Разделение по равноправию весьма редко, если вообще существует; ведёт к напряжённости
    * Single-party system/Однопартийная система: Без избирательного соревнования партия не имеет побуждения управлять честно
    * Totalitarianism/Тоталитаризм: Подавление индивидуальности ведёт к напряжённости, вдобавок одобренный способ жизни никогда ещё не был годен для всех
    * Victimless crime/Преступление без жертв: Подавление безопасного поведения создаёт субкультуру людей, постоянно-живущих-по-другим-законам, для которых эта правовая система является врагом
    * Witch hunt/Охота на ведьм: Легко отыскать козла отпущения, но если проблема никогда не решается в действительности, результатом будет являться поиск всё новых и новых козлов отпущения
    * Year Zero/Нулевой Год: Социальное изменение является долгим процессом, ускорение его влечёт катастрофу

Шуточные

    * Public Morozov/Паблик Морозов: Класс-потомок, созданный в соответствии с этим антипаттерном, выдает по запросу все данные класса-предка, независимо от степени их сокрытия. Название данного анти-паттерна — это каламбур, основанный на созвучии ключевого слова public (паблик), часто означающего открытый доступ к методам и полям класса в объектно-ориентированных языках программирования, и имени пионера-героя Павлика Морозова, известного тем, что он выдал своего отца-кулака.

P.S. копирование описаний не закончено, так же стоит учитывать, что здесь далеко не все шаблоны, но на пока хватит. Разберёмся что к чему по мере поступления примеров

Это сообщение отредактировал(а) atomicxp - 21.6.2009, 04:19
PM MAIL WWW Skype GTalk Jabber   Вверх
mes
Дата 20.6.2009, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(atomicxp @  20.6.2009,  01:21 Найти цитируемый пост)
Шуточные

    * Public Morozov/Паблик Морозов: 

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



--------------------
PM MAIL WWW   Вверх
atomicxp
  Дата 20.6.2009, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Цитата(mes @  20.6.2009,  11:01 Найти цитируемый пост)
У него только название шуточное, а на самом деле это самый настоящий антипаттерн.

Пока не важно как их идентифицировали, главное что они есть. Может потом подправлю классификацию, да и описания надо получше написать и ещё дописать. Но на первое время хватит, здесь главное видны названия, то есть есть от чего отталкиваться.
PM MAIL WWW Skype GTalk Jabber   Вверх
atomicxp
  Дата 20.6.2009, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Абстрактная фабрика (Abstract Factory)

Для начала краткий курс знакомства с абстрактной фабрикой.

user posted image

Цитата(определение)
Порождающий шаблон проектирования, позволяющий изменять поведение системы, варьируя создаваемые объекты, при этом сохраняя интерфейсы

Цитата(Цель)
Предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов, не специфицируя их конкретных классов

Цитата(Плюсы)
* изолирует конкретные классы;
* упрощает замену семейств продуктов;
* гарантирует сочетаемость продуктов.

Цитата(Минусы)
* сложно добавить поддержку нового вида продуктов.

Применяется в построение GUI (окна и кнопки), компьютерных играх и так далее.

Изменённый пример из вики:
Код
#include <iostream>

// AbstractProductA
class ICar
{
public:
    virtual void info() = 0;
};

// ConcreteProductA1
class Ford : public ICar
{
public:
    virtual void info()
    {
        std::cout << "Ford" << std::endl;
    }
};

//ConcreteProductA2
class Toyota : public ICar
{
public:
    virtual void info()
    {
        std::cout << "Toyota" << std::endl;
    }
};

// AbstractProductB
class IEngine
{
public:
    virtual void getPower() = 0;
};

// ConcreteProductB1
class FordEngine : public IEngine
{
public:
    virtual void getPower()
    {
        std::cout << "Ford Engine 4.4" << std::endl;
    }
};

//ConcreteProductB2
class ToyotaEngine : public IEngine
{
public:
    virtual void getPower()
    {
        std::cout << "Toyota Engine 3.2" << std::endl;
    }
};

// AbstractFactory
class CarFactory
{
public:
    ICar* getNewCar()
    {
        return createCar();
    }

    IEngine* getNewEngine()
    {
        return createEngine();
    }

protected:
    virtual ICar* createCar() = 0;
    virtual IEngine* createEngine() = 0;
};

// ConcreteFactory1
class FordFactory : public CarFactory
{
protected:
    // from CarFactory
    virtual ICar* createCar()
    {
        return new Ford();
    }
    virtual IEngine* createEngine()
    {
        return new FordEngine();
    }
};

// ConcreteFactory2
class ToyotaFactory : public CarFactory
{
protected:
    // from CarFactory
    virtual ICar* createCar()
    {
        return new Toyota();
    }
    virtual IEngine* createEngine()
    {
        return new ToyotaEngine();
    }
};

void Testing(CarFactory* curFactory)
{
    ICar* myCar = NULL;
    IEngine* myEngine = NULL;

    myCar = curFactory->getNewCar();
    myCar->info();
    myEngine = curFactory->getNewEngine();
    myEngine->getPower();

    delete myCar;
    delete myEngine;
}

int main()
{
    CarFactory* curFactory = NULL;
    ToyotaFactory toyotaFactory;
    FordFactory fordFactory;

    // Тестируем фабрику Тойоты
    curFactory = &toyotaFactory;
    Testing(curFactory);

    // Тестируем фабрику Форда
    curFactory = &fordFactory;
    Testing(curFactory);

    return 0;
}

Вывод консоли:
Код
Toyota
Toyota Engine 3.2
Ford
Ford Engine 4.4


Это сообщение отредактировал(а) atomicxp - 20.6.2009, 18:11
PM MAIL WWW Skype GTalk Jabber   Вверх
atomicxp
  Дата 20.6.2009, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Цитата(Lazin @  18.6.2009,  19:31 Найти цитируемый пост)
Цитата(unicuum @  18.6.2009,  17:33 Найти цитируемый пост)
Главный принцип ООП характеризовал бы как - "Разделяй и властвуй".

тебе не кажется
Цитата(unicuum @  18.6.2009,  17:33 Найти цитируемый пост)
Чтобы скомбинировать методы в одном классе, они должны быть по настоящему связаны.
что ты сам себе противоречишь?

Цитата(wiki: Разделяй и властвуй)
Разделяй и властвуй (англ. divide and conquer) — в информатике важная парадигма разработки алгоритмов. Основана на рекурсивном разбиении решаемой задачи на две (или более) подзадачи того же типа, но меньшего размера. Разбиения выполняются до тех пор, пока все подзадачи не окажутся элементарными.

Типичный пример — алгоритм быстрой сортировки. Чтобы отсортировать массив чисел по возрастанию, он разбивается на две равные части, каждая сортируется, затем отсортированные части сливаются в одну. Эта процедура применяется к каждой из частей до тех пор, пока не останется отсортировать массивы длины 1 или 2. Время выполнения этого алгоритма в среднем пропорционально nlogn, тогда как более простые алгоритмы дают n², где n — размер исходного массива.

Цитата(wiki: Божественный объект)
В объектно-ориентированном программировании, Божественный объект — это объект, который хранит в себе слишком много, или делает слишком много. Божественный объект является примером анти-паттерна.

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

Программа, основанная на Божественном объекте не следует этому подходу. Вместо этого, основная часть функциональности программы кодируется в одном объекте. Так как этот объект хранит большое количество данных и имеет много методов, его роль в программе становится «божественной»(всеобъемлющей).

Вместо того, чтобы общаться друг с другом непосредственно, другие объекты полагаются на Божественный объект. Так как на Божественный объект ссылается так много кода, его обслуживание становится гораздо сложнее.

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

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

Когда поправляют мои определения, мне кажется, что остальные люди догматики (антишаблон проектировани: Dogmatic religion/Догма), но ведь эти определения даны вовсе не мною. Может быть я следую догмам, потому что сам являюсь догматиком с поправкой на то, что слепая вера в них не по мне, этим и объясняется желание объяснить, почему делают так, а не иначе.

А вот ещё одно интересное мнение на обсуждаемые нами правила. Скорее всего они действительно существовали от сотворения нашей вселенной, если такое вообще было.

Цитата
Порой мне кажется, что C++ - это не просто язык. При всей простоте и естественности его правил он допускает такие техники применения, для которых изначально никак не предназначался. Когда некоторое изобретение областью своего применения (или технологиями) выходит за изначально очерченные рамки, это всегда серьезный повод задуматься. Ибо есть основания полагать, что это не изобретение вовсе, а открытие. В соответствии с представлениями некоего Платона, математика является не просто средством, но набором вполне объективных соотношений, которые существовали всегда, в том числе до того, как были впервые открыты. С этой точки зрения, язык C++ - есть некая объективная в платоновском смысле сущность, которая существует независимо от наших знаний и представлений о ней. Он столь же реален, что и мнимая единица, формула Эйлера, теорема Гёделя. Когда Бьярн Страуструп создал этот язык, это было не изобретение, а открытие - его разум соприкоснулся с абстрактным миром метафизической истины, состоящим из вполне объективных, но невидимых простому обывателю сущностей, соотношений, закономерностей. Говорить о превосходстве других языков перед C++ - все равно, что сравнивать научно доказанные факты с языческими суевериями.

PM MAIL WWW Skype GTalk Jabber   Вверх
atomicxp
  Дата 21.6.2009, 00:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Рассмотрим абстрактные фабрики более внимательно. Как известно любая система состоит из элементов, эти части называют элементарными. Именно с ними оперируют люди, когда собирают или пересобирают свои системы. Помимо этого, сами элементы могут состоять из элементов по некой другой классификации. Иными словами хотя для нас эти элементы уже не делятся на подэлементы и являются сборками, с другой стороны их можно рассматривать на более глубоком уровне.

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

abstract interface
Код
class AbstractInterface
{
 protected:
    ~AbstractInterface(){}
 public:
    virtual void ma() = 0;
    virtual void mb() = 0;
};

object interface
Код
class ObjectInterface
{
 public:
    virtual ~ObjectInterface(){}
 public:
    virtual void ma() = 0;
    virtual void mb() = 0;
};

пример использования:
Код
#include <iostream>

using namespace std;

class AbstractInterface
{
 protected:
    ~AbstractInterface(){ cout << "Desctruction AbstractInterface" << endl; }
 public:
    virtual void ma() = 0;
    virtual void mb() = 0;
};

class ObjectInterface
{
 public:
    virtual ~ObjectInterface(){ cout << "Desctruction ObjectInterface" << endl; }
 public:
    virtual void ma() = 0;
    virtual void mb() = 0;
};

class ClassAI : public AbstractInterface
{
 public:
    ~ClassAI(){ cout << "Desctruction ClassA" << endl; }
 public:
    void ma()
    {
        cout << "ClassAI: Method A" << endl;
    }
    void mb()
    {
        cout << "ClassAI: Method B" << endl;
    }
};

class ClassOI : public ObjectInterface
{
 public:
    ~ClassOI(){ cout << "Desctruction ClassB" << endl; }
 public:
    void ma()
    {
        cout << "ClassOI: Method A" << endl;
    }
    void mb()
    {
        cout << "ClassOI: Method B" << endl;
    }
};

void Testing()
{
    cout << "Testing ObjectInterface" << endl;

    ClassOI* classOI = new ClassOI();

    classOI->ma();
    classOI->mb();

    ObjectInterface* objectInterface = classOI;

    objectInterface->ma();
    objectInterface->mb();

    delete objectInterface; // удаление через интерфейс разрешено
    //delete classOI; // удаление через объект разрешено

    cout << '\n' << "Testing AbstractInterface" << endl;

    ClassAI* classAI = new ClassAI();

    classAI->ma();
    classAI->mb();

    AbstractInterface* abstractInterface = classAI;

    abstractInterface->ma();
    abstractInterface->mb();

    //delete abstractInterface; // удаление через интерфейс запрещено
    delete classAI; // удаление через объект разрешено
}

int main()
{
    Testing();

    return 0;
}

Вывод консоли:
Код
Testing ObjectInterface
ClassOI: Method A
ClassOI: Method B
ClassOI: Method A
ClassOI: Method B
Desctruction ClassB
Desctruction ObjectInterface

Testing AbstractInterface
ClassAI: Method A
ClassAI: Method B
ClassAI: Method A
ClassAI: Method B
Desctruction ClassA
Desctruction AbstractInterface

В примере из вики для построения абстрактной фабрики использовались объектные интерфейсы способные вызывать утечку памяти. Такой интерфейс вывел бы:
Код
Testing ObjectInterface
ClassOI: Method A
ClassOI: Method B
ClassOI: Method A
ClassOI: Method B

Вместо:
Код
Testing ObjectInterface
ClassOI: Method A
ClassOI: Method B
ClassOI: Method A
ClassOI: Method B
Desctruction ClassB
Desctruction ObjectInterface

Кстати, насчёт утечек памяти и всего прочего. В источниках информации посвящённых C++ этому уделяется огромное значение, что не совсем понятно. Не проще ли тупо использовать готовые реализованные шаблоны проектирования, которые гарантированно не вызовут утечек, чем каждый раз надоедать программистам со всякой ерундой.

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

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

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

А теперь представим, что программист не удалил объекты. И правда, он не обязан знать тонкости реализации (одно из правил книги «Совершенный код»). Причём программист ведь даже не видит, что объект создаётся, он видит только открытую часть, а она называется получить - get, а не создать - create. Следовательно текущая реализация абстрактной фабрики уже требует исправления по нескольким пунктам.
PM MAIL WWW Skype GTalk Jabber   Вверх
mes
Дата 21.6.2009, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(atomicxp @  20.6.2009,  23:37 Найти цитируемый пост)
Причём программист ведь даже не видит, что объект создаётся, он видит только открытую часть, а она называется получить - get, а не создать - create

Не понял откуда Вы взяли get, когда даже на приведенной Вами схеме методы называются Create smile





--------------------
PM MAIL WWW   Вверх
atomicxp
  Дата 21.6.2009, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Цитата(mes @  21.6.2009,  11:38 Найти цитируемый пост)
Не понял откуда Вы взяли get, когда даже на приведенной Вами схеме методы называются Create smile

Из приведённого кода, откуда ещё, а у Александреску это называется Make. Даже не знаю, стоит ли помимо вики ещё его пример приводить, уж он то извратился по максимуму со своими шаблонами.
PM MAIL WWW Skype GTalk Jabber   Вверх
mes
Дата 21.6.2009, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(atomicxp @  21.6.2009,  11:35 Найти цитируемый пост)

Из приведённого кода, откуда ещё, 

getNew.. и get .. не одно и то же. К тому же  никто не обязывает именовать функции как в примере и ничто не мешает подобрать более подохдящие названия для интерфейса.



--------------------
PM MAIL WWW   Вверх
atomicxp
  Дата 21.6.2009, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 2.5.2009
Где: Удмуртия, Ижевск

Репутация: 1
Всего: 1



Цитата(mes @  21.6.2009,  14:29 Найти цитируемый пост)
getNew.. и get .. не одно и то же.

Так и CreateProductA() и CreateProductB() не одно и тоже с Create
Цитата(mes @  21.6.2009,  11:38 Найти цитируемый пост)
Не понял откуда Вы взяли get, когда даже на приведенной Вами схеме методы называются Create smile

Лучше скажи как ты лично оцениваешь эффективность использования абстрактной фабрики в реальных примерах.
PM MAIL WWW Skype GTalk Jabber   Вверх
mes
Дата 22.6.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(atomicxp @  21.6.2009,  13:40 Найти цитируемый пост)
Лучше скажи как ты лично оцениваешь эффективность использования абстрактной фабрики в реальных примерах. 

положительно smile 


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1449 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.