7 / 7 / 0
Регистрация: 18.10.2008
Сообщений: 49
|
||||||
1 | ||||||
Factory Method14.10.2009, 20:11. Показов 3306. Ответов 4
Метки нет (Все метки)
Начал разбираться с фабричным методом нашел пример в интеренете и некоторые моменты кода не понимым :]
прошу помощи в поиснении кода некоторых моментах кода, пометил эти места коментом //
0
|
14.10.2009, 20:11 | |
Ответы с готовыми решениями:
4
Курсовая работа Паттерн «Абстрактная фабрика/Abstract Factory» Abstract Factory, переделка примера из книги Александреску с variadic templetes Use the method of Erathosfen Get-Method не работает |
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
|
|
14.10.2009, 21:17 | 2 |
Класс Product - абстрактный класс, определяющий интерфейс. Абстрактный - значит, создавать экземпляры этого класса нельзя, создавать можно только его потомков. virtual обозначает функцию, которая вызывается через таблицу. =0 означает, что виртуальный метод не определён (это и делает класс абстрактным). В объекте хранится информация о таких функциях, позволяющая осуществлять их вызов (указатель на таблицу виртуальных методов, но сейчас это неважно). Чтобы потомок такого класса можно было создать, в нём должны быть определены все занулённые в предках виртуальные функции, тогда такой класс станет конкретным и можно будет создавать его объекты.
В твоём случае можно создавать объекты классов ConcreteProductA и ConcreteProductB, а обращаться к этим объектам через указатель на класс Product. Обрати внимание - фактические типы объектов разные, а обращение к ним происходит через указатель одного и того же типа. Это называется полиморфизм - возможность одинаковым образом работать с объектами разных типов. При этом благодаря тому самому virtual при обращении к getName будет происходить обращение именно к той функции, которую переопределил класс-потомок. Аналогичным образом определён класс-создатель для продуктов и его потомки - создатели для продуктов A и B. В функции main создаётся массив из 2 указателей на создателя-предка, но создаётся не сам предок Creator, а два его разных потомка. Поскольку они оба произошли от Creator, указатели на эти объекты легко преобразуются к типу указателя на предка. Затем по очереди у каждого из этих объектов вызывается виртуальный метод, создающий продукт. Поскольку объекты разные, а метод виртуальный, вызывается сначала ConcreteCreatorA::FactoryMethod(), а потом ConcreteCreatorB::FactoryMethod(). В результате на первом шаге локальному указателю на Product присваивается адрес на свежесозданного ConcreteProductA, а на втором шаге - ещё более свеженького ConcreteProductB. Оба указателя неявно приводятся к типу Product. Затем происходит вызов виртуального метода getName, а раз он виртуальный, то вызывается метод, который определён в реальном классе объекта. Таким образом, сначала печатается "ConcreteProductA", а затем - "ConcreteProductB". Общий подход таков: допустим, у тебя есть набор различных, но родственных по смыслу объектов. Ты определяешь некоторый абстрактный класс-интерфейс. В нём ты определяешь ТОЛЬКО виртуальные методы, соответствующие общим для всех объектов операциям. Делаешь их чистыми (т.е. =0) и не определяешь. Делаешь свои конкретные классы потомками этого интерфейса и определяешь там нужные для них данные, дополнительные операции, и определяешь ВСЕ операции интерфейса так, чтобы они правильно работали именно с этим классом. Дальше ты можешь собрать в одну коллекцию объекты разного типа и размера, пользуясь указателями на их общий предок. Ты можешь пройтись по всей коллекции циклом, вызывая какую-то из операций, определённых в интерфейсе. При этом за счёт волшебного слова virtual для каждого объекта из коллекции будет автоматически вызываться операция, определённая в его классе.
1
|
MCSD: APP BUILDER
8794 / 1073 / 104
Регистрация: 17.06.2006
Сообщений: 12,602
|
|
14.10.2009, 21:28 | 3 |
ILJON,
перед тем как лезть в паттерны, сначала разберись с тремя основными китами C++ (два из них используются в этот примере - наследование и полиморфизм)
0
|
7 / 7 / 0
Регистрация: 18.10.2008
Сообщений: 49
|
|
14.10.2009, 21:52 [ТС] | 4 |
верно ли я понял
Product* product = creators[i]->FactoryMethod(); Product* product // декларируем ссылку на класс Product creators[i]->FactoryMethod(); // вызываем функцию FactoryMethod() и в зависимости от того что у нас в creators[i] путь нашь идет дальше в ConcreteCreatorA (или ConcreteCreatorB) и уже от туда у нас возвращеается ConcreteProductA() (или ConcreteProductB()) cout<<product->getName(); // а здесь уже исходя из того что нам вернулось ConcreteProductA или ConcreteProductB мы и выбираем в какой getName нам идти верно я понял? :]
0
|
1674 / 1046 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
|
|
16.10.2009, 21:15 | 5 |
верно
1
|
16.10.2009, 21:15 | |
16.10.2009, 21:15 | |
Помогаю со студенческими работами здесь
5
Template Method Pattern Template Method Pattern Допустима ли запись вида void method(T *& member)? (ссылка на указатель) <method name> is not a member of <class> при любом типе возвращаемого значения, кроме int Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |