Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Теоретический вопрос о моделях в MVC фреймворках

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: и способе возврата вычисляемых данных.
LukiDuki1980
Отправлено: 19 Апреля, 2015 - 15:58:40
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2015  


Помог: 0 раз(а)




Вопрос у меня не конкретно к какому-то фреймворку, а в целом, так скажем по теории.

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

Раньше, скажем в PHP, это решалось просто, к возвращенному массиву просто добавляли новые значения и возвращали весь список, а как решать эту проблему на уровне текущих абстракций фреймворков? В класс (отражающий таблицу) добавлять дополнительные поля? Или же создать отдельный класс, который включает как вычисляемые данные, так и объект с БД?
 
 Top
caballero
Отправлено: 20 Апреля, 2015 - 13:37:57
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




все зависит от реализации фреймворка и его архитектуры. поэтому "в теории" ответ смысла не имеет.


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
LukiDuki1980
Отправлено: 20 Апреля, 2015 - 14:58:32
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2015  


Помог: 0 раз(а)




caballero пишет:
все зависит от реализации фреймворка и его архитектуры. поэтому "в теории" ответ смысла не имеет.

У меня для вас плохие новости, дело в том что абстракция укладывается в абстракцию и речь тут скорее - "как правильно сделать в рамках дизайна в MVC модели". Я конечно понимаю, что очень трудно понимать на таком уровне абстракций - как проектирования кода, но другие я думаю смогут без конкретного фреймворка.
 
 Top
DeepVarvar Супермодератор
Отправлено: 20 Апреля, 2015 - 15:32:56
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




 
 Top
MiksIr
Отправлено: 20 Апреля, 2015 - 16:15:44
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


LukiDuki1980 пишет:
caballero пишет:
все зависит от реализации фреймворка и его архитектуры. поэтому "в теории" ответ смысла не имеет.

У меня для вас плохие новости, дело в том что абстракция укладывается в абстракцию и речь тут скорее - "как правильно сделать в рамках дизайна в MVC модели". Я конечно понимаю, что очень трудно понимать на таком уровне абстракций - как проектирования кода, но другие я думаю смогут без конкретного фреймворка.

"На уровне абстракций" модель вообще не имеет никакого отношения к базе данных. То, о чем вы пытаетесь говорить - это паттерн ActiveRecord, популярный в простых фреймворках за счет своей простоты.
Модель - это бизнес-логика. Но это не способ хранения данных где-то в сторадже. Как сохранять, поучать, удалять и прочее - это вообще выходит за рамки MVC.


-----
self-banned
 
 Top
LukiDuki1980
Отправлено: 20 Апреля, 2015 - 16:26:08
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Апр. 2015  


Помог: 0 раз(а)





Он не понял вообще сути, поэтому правильно сказать он не мог, я попробуй обрисовать кодом (возможно моя вина, что пытался текстом донести).

Условие, после обработки из БД формируется результат в виде некого объекта класса Post, в котором описаны поля таблиц (ORM иди ActiveRecord не важно).
Вопрос.
Как с точки зрения ООП дизайна поступить, то есть что вернуть контроллеру?


1) Просто вернуть массив, где одно значение это объект Post (результат из БД), а второй вычисленные данные.
CODE (htmlphp):
скопировать код в буфер обмена
  1. class Model {
  2.  
  3. public function getData(){
  4.   $query = "Query";
  5.   $post = $store->get($query);
  6.   $result = [
  7.     'post' => $post,
  8.     'smthParams' => $this->calculateSmth()
  9.   ];
  10.  
  11.   return $result;
  12. }
  13. ...
  14. }


2) Создать какой-то выше по уровню класс типа OverPost, которые бы включал в себя объект (результат из БД), а второй вычисленные данные (по сути тот же массив только в обертке ООП со всеми плюшками).
CODE (htmlphp):
скопировать код в буфер обмена
  1. class Model {
  2.  
  3. public function getData(){
  4.   $query = "Query";
  5.   $post = $store->get($query);
  6.   $result = new OverPost()
  7.   $result->setPostData($post);
  8.   $result->setSmthParam($this->calculateSmth())
  9.  
  10.   return $result;
  11. }
  12. ...
  13. }



3) Заранее расширить класс Post, чтобы он содержал данные не только с таблиц БД, а так же вычисляемые данные, например:
Код:

CODE (htmlphp):
скопировать код в буфер обмена
  1. class Model {
  2.  
  3. public function getData(){
  4.   $query = "Query";
  5.   $post = $store->get($query);
  6.   $post->setSmthParam($this->calculateSmth());
  7.   return $post;
  8. }
  9. ...
  10. }


В общем какой вариант будет правильней, с точки зрения дизайна кода, с точки зрения MVC и с точки зрения нынешнего стиля фреймворков?

(Отредактировано автором: 20 Апреля, 2015 - 16:28:17)

 
 Top
LIME
Отправлено: 20 Апреля, 2015 - 17:40:36
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




модель никак не связана с таблицами в бд
если в "теории" то модель призвана отражать некие объекты(в широком смысле)
часто это объекты реального мира но не обязательно
какие они поддерживают действия и содержат данные никак не зависит от таблиц
в конструктре можно брать данные из таблиц к ним добавлять день недели и бох знает что еще
и вообще лучше если модель будет использовать другие объекты(в узком смысле)) ) - механизмы для сохранения/чтения из бд
тогда можно менять способ хранения не меняя логику модели вообще
(Добавление)
само слово "модель" должно подсказывать что этот зверь моделирует нечто
поведение и данные
но никак не способ хранения
 
 Top
tato
Отправлено: 22 Апреля, 2015 - 09:02:48
Post Id



Посетитель


Покинул форум
Сообщений всего: 468
Дата рег-ции: Сент. 2011  
Откуда: Владивосток


Помог: 8 раз(а)




PHP:
скопировать код в буфер обмена
  1.  
  2. class Order {
  3.             public
  4.                 $count,
  5.                 $price;
  6.  
  7.             public static function findByPk($pk) {
  8.                 $data = []; // load data from db by pk
  9.                 $model = new self;
  10.                 $model->count = $data['count'];
  11.                 $model->price = $data['price'];
  12.  
  13.                 return $model;
  14.             }
  15.  
  16.             public function getTotal() {
  17.                 return $this->count * $this->price;
  18.             }
  19. }
  20.  
  21. $order = Order::findByPk(1);
  22. echo $order->count;
  23. echo $order->getTotal();
  24.  


----
решил упростить
(Добавление)
А вообще зависит от ситуации.
Если что-то надо сделать с данными из одного объекта то смело делаем метод как в примере выше.

Если Есть кучка объектов(например Order, OrderItem, Product) они связаны между собой и надо что-то считать основываясь на всех трех объектах, то лучше сделать отдельную модель членами которой будут эти объекты и методы работы с ними.

Это вот фигово, что в статьях и книгах объекты стараются сопоставить с "объектами реального мира", потом проблемы у людей возникают.
(Добавление)
PHP:
скопировать код в буфер обмена
  1.  
  2. class OrderProvider {
  3.     public
  4.         $order,
  5.         $orderItems,
  6.         $products;
  7.  
  8.     public static function findByUser($user)
  9.     {
  10.         $model = new self;
  11.         $model->order      = Order::findByUser($user);
  12.         $model->orderItems = OrderItem::findAllByOrder($this->order->id);
  13.         $model->products   = Product::findAllByItems($this->orderItems);
  14.  
  15.         return $model;
  16.     }
  17.  
  18.     public function getEachTotal() {
  19.         $result = [];
  20.  
  21.         foreach($this->orderItems as $id => $item) {
  22.             $result[$id] =
  23.                 $item->count * $this->products[$item->product_id]->price;
  24.         }
  25.  
  26.         return $result;
  27.     }
  28. }
  29.  
  30. $model = OrderProvider::findByUser(1);
  31. $model->getEachTotal();
  32.  

(Отредактировано автором: 22 Апреля, 2015 - 09:26:32)



-----
просто ?: сложно
 
 Top
LIME
Отправлено: 22 Апреля, 2015 - 15:41:38
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




tato то что ты показал никак не противоречит всему сказанному выше и тем более не отвечает на вопрос
и еще
почему не конструктор? зачем его вызывать в статическом методе? почему не вызвать его напрямую?
если ты видел что модель формируется статическим методом и то там наверное это был фабричный метод
не?
tato пишет:
Это вот фигово, что в статьях и книгах объекты стараются сопоставить с "объектами реального мира", потом проблемы у людей возникают.
сказал ты и привел пример объектов из реального мира))
tato пишет:
public static function findByUser
а если у юзера более одного заказа?
тут скорее коллекция
но это к делу не относится
 
 Top
tato
Отправлено: 23 Апреля, 2015 - 02:45:57
Post Id



Посетитель


Покинул форум
Сообщений всего: 468
Дата рег-ции: Сент. 2011  
Откуда: Владивосток


Помог: 8 раз(а)




[quote=LIME][/quote]

Как-то лень полностью реализацию писать, еще тут проверок параметров нет, валидации полей, и т.д.

Статичный, конструктор не принципиально. Просто для примера завел т.к. конструктор есть конструктор, а findByUser говорит, что вообще происходит.

Если много то стоит сделать findAllByUser().

OrderProvider и есть модель не из реального мира.


-----
просто ?: сложно
 
 Top
LIME
Отправлено: 23 Апреля, 2015 - 03:37:47
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




tato пишет:
а findByUser говорит, что вообще происходит

а новый заказ как тогда создать?
вот так бы логичнее было имхо:
PHP:
скопировать код в буфер обмена
  1. $order = new Order()->initByUser($userId);
хотя остается открытым вопрос что делать если у юзера более одного заказа?
тут как я уже говорил логичнее было бы создавать коллекцию моделей
ну да ладно

tato пишет:
OrderProvider и есть модель не из реального мира.
нет
это на самом деле и есть модель Order
заполненная данными из нескольких таблиц
и представляющая самый настоящий объект реального мира, но не отдельную таблицу
(Добавление)
хотя...всеже неоднозначная логика
вот например что за orderItems? нафига оно вообще надо?
видимо это типа "модель" для таблицы связи продуктов с заказом?
вот тот самый случай когда модель для таблицы вообще не надо было писать
логику работы с двумя таблицами логично было бы заключить в одну модель
это одна сущность
 
 Top
tato
Отправлено: 23 Апреля, 2015 - 08:24:26
Post Id



Посетитель


Покинул форум
Сообщений всего: 468
Дата рег-ции: Сент. 2011  
Откуда: Владивосток


Помог: 8 раз(а)




Да хоспади.. Мы тут заказы реализовываем или размышляем в каком месте калькулировать результат.


LIME пишет:
хотя остается открытым вопрос что делать если у юзера более одного заказа?

PHP:
скопировать код в буфер обмена
  1.  
  2. $order  = Order::model()->find(); // ->findByPk(), ->findByAttributes(), etc...
  3. $orders = Order::model()->findAll(); // ->findAllByAttributes, etc...
  4. $new_order = new Order;
  5. $new_order->setAttributes([...]);
  6. $new_order->save();
  7.  


LIME пишет:
это на самом деле и есть модель Order
заполненная данными из нескольких таблиц
и представляющая самый настоящий объект реального мира, но не отдельную таблицу

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

Если бы итемы были просто связью многие ко многим, то да нет смысла модель заводить, но в примере выше они еще хранят количество заказных продуктов(еще там может быть денармолизована стоимость_продукта * количество, какой-нибудь статус, и т.д.).


-----
просто ?: сложно
 
 Top
LIME
Отправлено: 23 Апреля, 2015 - 08:59:54
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




хотел было забросить но... почему бы и не продолжить...сам себе получше уясню тему
tato первое - никто тебя не называет дурачком и твой код ужасным
в нем есть некоторые изъяны которые я увидел и не более того
прекрати отбиваться и начни рассуждать)
---
всякие там findBy getBy лучше реализовать в отдельном классе
типа Resource
и внедрять его в модель
таким образом мы уйдем в модели от зависимости от хранилища
например ты захочешь все текущие заказы хранить в памяти
тогда просто применяешь другой Resource
в модели лучше если будут только методы этой сущности но не методы ее получения и сохранения
LIME пишет:
и вообще лучше если модель будет использовать другие объекты(в узком смысле)) ) - механизмы для сохранения/чтения из бд
тогда можно менять способ хранения не меняя логику модели вообще

мне кажется это удобнее (и не только мне)

tato пишет:
работать будет не удобно
как раз удобно
весь смысл городить модели - это удобство
ведь от клиента тебе приходит все вместе? вот и работай с этой сущностью целиком
подумай об этом
tato пишет:
К примеру мне нужен отчет по продажам продукта
это уже класс отчета в котором можно применить Resource или вообще прямой запрос
модель чуть для другого нужна
чтобы локализовать работу с заказами(не получение отчета а именно работу клиента/магазина/службы доставки с заказом)
tato пишет:
Да хоспади..
ну в принципе пойдет и так)

(Отредактировано автором: 23 Апреля, 2015 - 09:03:58)

 
 Top
tato
Отправлено: 24 Апреля, 2015 - 06:15:19
Post Id



Посетитель


Покинул форум
Сообщений всего: 468
Дата рег-ции: Сент. 2011  
Откуда: Владивосток


Помог: 8 раз(а)




[quote=LIME][/quote]

Ну опять таки недостаток примера который Я привел.
Ладно, что бы было проще, это Yii way. На самом деле за findBy... нет прямой выборки из базы, там обращение к CCommandBuilder который по сути и является ресурсом или типо того.


-----
просто ?: сложно
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB