Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проектирование архитектуры Склада 
:(
    Опции темы
weldpua2008
  Дата 8.3.2013, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрый день
Пишу приложение "Склад":
Цитата

Программа складского учета позволяет вести учет товарно-материальных ценностей (ТМЦ) и включает в себя такие операции: приход, расход, перемещение между складами(магазинами), инвентаризация, списание, просмотр остатков и резервов, отслеживание движения ТМЦ во времени... Учет по нескольким магазинам-складам.



Цитата

Переучёт раз в 1-3 месяца.

1.До переучёта нужно видеть всю историю по товару: кто и сколько принял на склад, кто и сколько продал, когда, по каким ценам?
2.Иметь актуальный склад (да считаем, что Приход/Уход/Продажу люди заполняют) по каждому магазину.
3.Получить "сверочные" данные для реального переучета.
4.После переучёта (можно конечно же непрерывно сохранять) данные можно архивировать, менять структуры, хранить по другому.
Аналитика по продажам/складу(что лучше продаётся, какая прибыль с данного товара за год, определение сезонности и т.д.) не в риалтайме. Другими словами данные должны занимать меньше места и давать меньше нагрузку.


Набрасал примерную схему базы данных

user posted image

Помогите с шаблонами проектирования и архитектурой
PM MAIL   Вверх
Fortop
Дата 9.3.2013, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

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



С шаблонами проектирования чего?


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
weldpua2008
Дата 9.3.2013, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Fortop @ 9.3.2013,  19:59)
С шаблонами проектирования чего?

добрый вечер
Цитата

шаблон проектирования или паттерн (англ. design pattern) — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.

раньше их не использовал — всегда писал код (наверное это и есть знаменитый быдло-код), который описывает то что "происходит" (без попыток убрать дубли в коде, с последующим переписыванием).

Теперь есть желание встать на правильный путь. В этом и прошу помощи...

Для работы с базой буду использовать godb

Во первых:
Реализация функций доступа (ACL) — когда пользователи или конкретная группа имеют возможность выполнять данное действие (Читать/Писать/Просматривать). Разрешения храняться в базе данных

Вопрос - лучше проверять при действии (сохранение/просмотр/удаление/обновление) или дополнительно при недостаточности прав менять html-код. 
Отключаем кнопку сохранить, если нет прав:
Код

<button type="button" disabled>Сохранить!</button> 


на одном блоге "Шаблон проектирования фабрика (factory method)" - в данном виде он не применим тут (там статически заданы группы и пользователи)
Код

/*
Далее в примере видим UserFactory, в котором и находится фабричный метод. Допустим, есть три пользователя: guest, admin, customer. У нас есть статический метод Create, который получает имя на входе (проверяем, есть такое имя или нет). В switch смотрим, если он админ — возвращаем экземпляр класса admin, если он гость — возвращаем экземпляр класса guest и т.д.
*/
abstract class User {
   protected $name = null;
   function _construct($name){
      $this->name = $name;}
   function getName(){
      return $this->name;}
//Методы определения прав доступа
   function hasReadPermission(){
      return true;}
   function hasModifyPermission(){
      return false;}
   function hasDeletePermission(){
      return false;}
//классы-наследники от базового класса
class GuestUser extends User {} //наследует все из базового класса
class CustomerUser extends User { //может читать и изменять
   function hasModifyPermission(){
      return true;} //
}
class AdminUser extends User { //админ, может все
   function hasmodifyPermission(){
      return true;}
   function hasDeletePermissoin(){
      return true;}
   function wantsFlashInterface(){
      return false;}
}
//фабричный метод
class UserFactory {
   private static $users = array ("Max"=>"admin", "Mikki"=>"guest", "Ann"=>"customer");
   static function Create($name){
      if(!isset(self::$users[$user])){
         //выскочит ошибка - пользователь не зарегистрирован
      }
      switch (self::$users[$user]){
         case "guest":return new GuestUser ($name);
         case "customer":return new CustomerUser ($name);
         case "admin":return new AdminUser ($name);
         default://ошибка - неизвестный тип пользователя}
   }
}




на хабре в коментариях:
Цитата

Как вариант, механизм контроля доступа можно реализовать в виде экранирующих прокси-объектов (Proxy pattern) перед доменными моделями, зависимых от некого сервисного обьекта (Singleton pattern, Object pool).


Цитата

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

Очевидно, такую систему очень просто прикрутить к уже существующей онтологии доменных моделей. 


вот про Аспектно-ориентированное программирование c Go! AOP PHP слышал
Цитата

Прочитайте про аспектно-ориентированное программирование.

Основная идея, что к методу/функции можно довешивать «сбоку» дополнительный функционал. Попробуйте поискать существующую библиотеку АОП, а не писать собственный «велосипед». 


тут есть интереная мысль:

Цитата

Суть проблемы очень проста — незачем смешивать представление и систему управления доступом.

Проблема решена была в два приёма:

    Надстройка над убогой системой прав, которая позволяла разделить списки доступа и представление
    Предоставление возможности использовать в шаблонах smarty эту надстройку



отсюда можно почерпнуть интересную идею в хранении всех прав в виде Json

Цитата

Для любителей JSON, можно использовать вместо serialize/unserialize => json_encode/json_decode, которые по идее должны работать быстрее и занимать меньше места в БД.

Для любителей более человечных названий групп, ничего не потребуется для того, чтобы все GroupID сменить с int на string.

Можно использовать $_SESSION, если пользователь залогинился, для запоминания всех его прав $User->current_user->rights (и другой пользовательской информации), чтобы не обращаться к базе данных и не производить лишних действий. Единственный минус — чтобы пользователю сменить права доступа, ему необходимо будет перелогиниваться.


Во вторых:
Есть обьекты: товар(он храниться на складах), операции Приход/Уход/Списание товара, Пользователи, склады, привилегии(ACL) и т.д.

Сами операции для их сохранения, редактирования, обновления, удаления и просмотра - можно ли использовать некий шаблон проектирования? (например фабрику?) 
 

например если классами:
Код

/* Работа с обьектами Пользователи */
Class Users {
function createUser() {}
function deleteUser() {}
function modifyUser() {}
}


/* Работа с обьектами Товар */
Class Goods {
function createGoods() {}
function deleteGoods() {}
function modifyGoods() {}
}


/* Работа с обьектами Склад */
Class Warehouse {
function createWarehouse() {}
function deleteWarehouse() {}
function modifyWarehouse() {}
}




Имеет ли смысл разбивать функции просмотра и модификации (создания/удаления/редактирования) на разные классы? Ведь для некоторых классов нужно кеширование (привилегии (ACL), Склады, Пользователи), причём это не обязательно какой-то определённый вид кеша(мемкеш).

И самый главный вопрос: 
Как проектировать систему, что бы она была модульной?
Был склад: Приход/Уход/Списание.
Добавили модуль "Купон": теперь при Реализации товара покупатель получает скидку. При этом консистентность склада (Приход- (Уход+Реализация+Списание) = 0 )



Это сообщение отредактировал(а) weldpua2008 - 10.3.2013, 01:29
PM MAIL   Вверх
Fortop
Дата 10.3.2013, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

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



weldpua2008, для начала стоит понять, что никакой шаблон проектирования не налезет на систему. В силу сложности системы.
Поэтому можно говорить об уместности использования того или иного шаблона для реализации какой-либо части.

Вот отсюда давайте и начинать плясать.
А не со стека "новинок", которые хочется потыкать.

http://en.wikipedia.org/wiki/Software_design_pattern
http://en.wikipedia.org/wiki/Design_Patterns


Цитата(weldpua2008 @  9.3.2013,  22:33 Найти цитируемый пост)
Сами операции для их сохранения, редактирования, обновления, удаления и просмотра - можно ли использовать некий шаблон проектирования?

Можно. 
Active Record, Table data gateway, Row data gateway, Data mapper и т.д.
Какой нужен?

http://martinfowler.com/eaaCatalog/index.html

Цитата(weldpua2008 @  9.3.2013,  22:33 Найти цитируемый пост)
Теперь есть желание встать на правильный путь. В этом и прошу помощи...

Рекомендую начинать с того, что мешает самому и не нравится.
Например - мешает дублирование кода. Вот от него и пляшем - смотрим как мы можем избежать его.

Цитата(weldpua2008 @  9.3.2013,  22:33 Найти цитируемый пост)
Как проектировать систему, что бы она была модульной?

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

Исходите из того, что части вашего кода должны знать как можно меньше друг о друге.
Т.е., например, мне нужны данные определенного формата, а откуда я получаю эти данные (из кеша или БД) - не имеет значения.



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
weldpua2008
Дата 10.3.2013, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Fortop @  10.3.2013,  17:18 Найти цитируемый пост)
для начала стоит понять, что никакой шаблон проектирования не налезет на систему. В силу сложности системы.

это понятно ;)

Цитата(Fortop @  10.3.2013,  17:18 Найти цитируемый пост)


Цитата(weldpua2008 @  9.3.2013,  22:33 Найти цитируемый пост)
Цитата

Сами операции для их сохранения, редактирования, обновления, удаления и просмотра - можно ли использовать некий шаблон проектирования?


Можно. 
Active Record, Table data gateway, Row data gateway, Data mapper и т.д.
Какой нужен?

Разве это не способ чтения/записи данных из базы данных?
Я про организацию/структуру/архитектуру самих классов, которые сохраняют и читают обьекты. И то как их проектировать. Допустим, что мне нужно товар, склады, пользователей и так далее хранить не в базе данных, а на диске или "неком" хранилище? А если нужно кеширование? А если нужно для некоторых обьектов добавить проверку или операцию?
Нужно менять весь код? (Например: Интернет-магазин на одном SQL-сервере, а текущее приложение Склада на другом, при этом синхронизация идёт с помощью промежуточного приложения).

Структуру базы данных(картинка в начале) и библиотека для доступа к ней godb, которые использую.

Думаю, что Decorator (Wrapper)/Facade/Proxy подойдет для организации (а там обьект с каким паттерном  Active Record/Table data gateway/ Data mapper или же на какой библиотеке Propel/Doctrine не важно???) операций чтения/записи обьектов в систему хранения данных.

Цитата(Fortop @  10.3.2013,  17:18 Найти цитируемый пост)
Рекомендую начинать с того, что мешает самому и не нравится.
Например - мешает дублирование кода. Вот от него и пляшем - смотрим как мы можем избежать его.

да, как?

Для себя здесь нашел подсказку как не нарушать  принцип единственной ответственности :
Цитата

Типичный программист внесет вызов нужных методов в код методов «кушать» и «спать», нарушив принцип единственной ответственности каждого из этих методов.   далее попадается код, который делает разные вещи в одном месте и нет никакого намека на то, что этот кусок кода должен быть тут.

Следующая категория программистов ощущает подвох в том, что нужно изменять логику метода и они идут в другую крайность: делают новые методы в классе, которые объединяют в себе логику нескольких методов. А вам знакомы методы вида «мытьРукиAndКушать()»? 


Я и сам на такое не раз попадался ;)
Там же есть решение этого вопроса: 
Цитата

Вообще с помощью классов описываются не только состояния но и процессы.
И в данном случае в классе Human не было бы метода eat. Был бы метод принимать пищу. А вот процесс кушать, был вынесен в отдельный класс








Цитата(Fortop @  10.3.2013,  17:18 Найти цитируемый пост)
Цитата(weldpua2008 @  9.3.2013,  22:33 Найти цитируемый пост)
Цитата

Как проектировать систему, что бы она была модульной?


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

Ну это Я понимаю. По сути дела в моём случае модули: ACL-ы, склады, товар, пользователи и так далее. 

Например права доступа не зависят от наличия/отсутствия пользователей. По сути это лишь метки/маски или иные признаки, что можно/нельзя делать с данным ресурсом. 
А вот логика(модуль логики) системы прав доступа реализует: "если у ресурса статья маска 'rrw', то группа 'Гости и Авторы' могут лишь читать её, но не изменять".
По крайней мере мне это кажется логичным, но не понятно как это реализовать.
Вот только 
PM MAIL   Вверх
Fortop
Дата 10.3.2013, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

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



Цитата(weldpua2008 @  10.3.2013,  20:27 Найти цитируемый пост)
Разве это не способ чтения/записи данных из базы данных?
Я про организацию/структуру/архитектуру самих классов, которые сохраняют и читают обьекты. И то как их проектировать.

В чем разница?

Код

class User {

    protected $storage = null;
    public function __construct(Storage $obj) {
        $this->storage = $obj
    }

    public function create($name) {
        $key = spl_object_hash($this);
        $this->storage->insert($key, $name);
    }
}

abstract Storage {
    abstract public function insert($key, $value);
}

class RedisStorage extends Storage {
    public function insert($key, $value) {
        $this->redisServer->set($key, $value);
    }
}

class SqlStorage extends Storage {
    public function insert($key, $value) {
        $this->sqlServer->query('insert into objects (id, value) values (?,?)', array($key => $value));
    }
}

$mysql = new SqlStorage(.....);
$redis = new RedisStorage(.....);
$userList = [new User($mysql), new User($redis)];

foreach ($userList as $user) {
    $user->create('sampleName');
}




Цитата(weldpua2008 @  10.3.2013,  20:27 Найти цитируемый пост)
да, как?

Разбить код на минимальные логически связанные участки и выделить их в методы/функции.
На примере библиотеки работы с БД уже можно было это увидеть.
Ведь не имеет значения какого рода данные будут сохраняться с ее помощью.


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
weldpua2008
Дата 11.3.2013, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Fortop @  10.3.2013,  22:30 Найти цитируемый пост)
Разбить код на минимальные логически связанные участки и выделить их в методы/функции.
На примере библиотеки работы с БД уже можно было это увидеть.

Кстати вопрос по поводу прав доступа. По идеи каждый класс должен решать свои задачи. 
Но когда идёт речь о проверки прав доступа к определённой операции получается зависимости. Теперь в наш клас, который Создаёт/Обновляет/Удаляет обьекты "User" явно задана логика проверки прав:
Код

/* было */
class User {
    public function create($name) {
        $key = spl_object_hash($this);
        $this->storage->insert($key, $name);
    }
}


/* стало */
class User {
    public function create($name) {
        $key = spl_object_hash($this);

     /* has_permition() - это упрощение */
     if(has_permition()){
        $this->storage->insert($key, $name);
      }else{
          echo "deny";
      }

    }
}

Ведь как мы проверяем права доступа?
  • По url'у  ( has_permition($url, $_SESSION['user_id']) (представим, что сменился урл - права потеряны)
  • Передавая ключ ( has_permition('CreateUser', $_SESSION['user_id']/$_SESSION['user_group_id'])  - упрощено )
  • has_permition() трансформируется в:
    Код

    <?php
    if ($this->role->isAdmin ){
                $this->storage->insert($key, $name);
            }
    ?>
  • еще варианты?...

PM MAIL   Вверх
Fortop
Дата 11.3.2013, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

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



Цитата(weldpua2008 @  11.3.2013,  12:47 Найти цитируемый пост)
Но когда идёт речь о проверки прав доступа к определённой операции получается зависимости.

Получаются.
От зависимостей полностью не избавится.

Два варианта.
Либо вы делаете проверку доступа на моменте работы с элементом управления (т.е. до вызова User->create())
Или каким-либо образом связываете свои модели с системой проверки прав (например, при помощи того же Dependency Injection).


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

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


 




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


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

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