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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ООП + PHP, ООП + PHP 
:(
    Опции темы
JackGmen
  Дата 1.4.2012, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пытаюсь разобраться с ООП, помогите кто в теме, пожалуйста.
Итак, к примеру, есть:
SMS сервер, у которого есть различные смс (обычные, отложенные, подписки), отличающиеся запросами к БД, также есть различные операторы к примеру МТС и Beeline, через которые эти смс я буду отправлять, как бы на этом все.
Что себе надумал я:
Код

$sms = new SMS();
$sms->getSMS();
$sms->sendSMS();


вот так подумал я должен работать смс сервер, но тут же возник вопрос, почему не просто $sms->sendSMS()? зачем я всунул $sms->getSMS()? где граница? что нужно логически выносить в отдельные методы?

вот кусок класса СМС сервера
Код

class SMS {
  private $_normalSMS;
  private $_subsSMS;
  
  function getSMS () {
    $this->_normalSMS = $this->getNormal();
    $this->_subsSMS = $this->getSubs();
  }
  
  function sendSMS () {
    $mts = new MTS();
    $mts->send();
    $beeline = new Beeline();
    $beeline->send();
  }
  
  ...
  ...
}



вот кусок Оператора
Код

class MTS extends SMS {
  
  function send () {
    $this->sendMTS($this->_normalSMS);
    $this->sendMTS($this->_subsSMS);
  }
  
  function sendMTS ($rows) { 
    // отправляем смс МТС
  }
}



Мне нужен совет, правильно ли я все делаю, или есть более рациональное решение?

PS код писал во время вопроса, на корректность не проверял ...
PM MAIL   Вверх
Sentox
Дата 1.4.2012, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

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



Вы смешали две разных абстракции.
Оператора и sms. Они раздельны и оператор не может быть подтипом (наследоваться) SMS.
В начале проектирования нужно определить абстракции и их интерфейсы (public) методы\свойства. Затем можно и спроектировать их взаимодействие между собой (если нужно паттерны применять).
Логически подумать, SMS не может отправлять саму себя (фактически SMS всего лишь структурно-информационная единица с примитивными методами по обработке текста\изображений), отправляют SMS операторы.
Очень помогает графическая документация например UML.

Это сообщение отредактировал(а) Sentox - 1.4.2012, 18:05
PM MAIL   Вверх
JackGmen
Дата 1.4.2012, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Sentox @ 1.4.2012,  17:55)
Вы смешали две разных абстракции.
Оператора и sms. Они раздельны и оператор не может быть подтипом (наследоваться) SMS.
В начале проектирования нужно определить абстракции и их интерфейсы (public) методы\свойства. Затем можно и спроектировать их взаимодействие между собой (если нужно паттерны применять).
Логически подумать, SMS не может отправлять саму себя (фактически SMS всего лишь структурно-информационная единица с примитивными методами по обработке текста\изображений), отправляют SMS операторы.
Очень помогает графическая документация например UML.

Если вы внимательно прочли вопрос, то должны были понять что класс SMS, это SMS сервер, который шлет все смс, а не одну смс как подумали вы ... немного объясню если не все понимают что я имел ввиду:
СМС сервер выбирает все смс, в методе getSMS, а потом в методе sendSMS их все отправляет, а в самом методе я могу определить каким оператором эти смс отправлять, ну а в самом операторе я уже могу определить какой тип смс отправлять ... вот такую структуру я себе сделал и спрашиваю, если способ эту структуру сделать гибче, паттерны читал, мой способ похоже на паттерн Facade ... 

Я уже немного начал разбираться ... но все равно не уверен что все правильно ...
PM MAIL   Вверх
Sentox
Дата 1.4.2012, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

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



Цитата(JackGmen @ 1.4.2012,  18:38)

Если вы внимательно прочли вопрос, то должны были понять что класс SMS, это SMS сервер, который шлет все смс, а не одну смс как подумали вы ... немного объясню если не все понимают что я имел ввиду:
СМС сервер выбирает все смс, в методе getSMS, а потом в методе sendSMS их все отправляет, а в самом методе я могу определить каким оператором эти смс отправлять, ну а в самом операторе я уже могу определить какой тип смс отправлять ... вот такую структуру я себе сделал и спрашиваю, если способ эту структуру сделать гибче, паттерны читал, мой способ похоже на паттерн Facade ... 

Я уже немного начал разбираться ... но все равно не уверен что все правильно ...

Я ещё раз утверждаю что смешаны абстракции, а то что Вы называете SMS сервером является абстракцией Operator (это в чистом коде называется дезинформацией, неправильно выбранным именем абстракции) от которой фактически должны  были бы наследованы все остальные подтипы операторов (MTC ...), так же этот класс бы заявлял контракты (интерфейсы) и являлся бы контроллером (facade) с композицией sms. Хотя я бы сделал на основе паттерна observers при котором бы была бы событийная схема при которой бы тип "Operator" (соответственно его наследующие классы) был бы наблюдателем за изменёнными данными то есть SMS.  То есть если бы пулл SMS наполненн оповещались наблюдатели и запускались соответственные процессы.

Это сообщение отредактировал(а) Sentox - 1.4.2012, 19:51
PM MAIL   Вверх
baldina
Дата 1.4.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



JackGmen, 
Код

class SMServer {
  public function get () { /* get all sms from DB */ }
  public function send () {
      foreach ($this->get() as $sms) {
         $sms->getOperator()->send ($sms->data);
      }
  }
}

class Operator {
   public function send ($data) {...}
}

class MTS extends Operator {...}
class Beeline extends Operator {...}

если хотите отправлять через одного оператора все сразу, можно например так
Код

class SMServer {
  private $operators = array();
  public function __construct () {
    $this->operators[] = new MTS;
    $this->operators[] = new Beeline;
  }
  public function get ($operator) { /* return all sms from DB */  }
  public function send () {
      foreach ($this->operators as $operator)
         foreach ($this->get($operator->name) as $sms)
            $operator->send ($sms->data);
  }
}

PM MAIL   Вверх
JackGmen
Дата 1.4.2012, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



baldina спасибо!

На основе вашего примера сделал так
Код

$sms = new SMServer();
$sms->send();


Классы:
Код

class SMServer {
    private $operators = array();
    
    public function __construct () {
        $this->operators[] = new MTS; // control operators
        $this->operators[] = new Beeline; //
    }
    
    public function send () {
        foreach ($this->operators as $operator)
            $operator->send ();
    }
}

abstract class Operator {
    private $_normalSMS;
    private $_subsSMS;
    
    private function __construct () {
        $this->_normalSMS = $this->getNormalSMS();
        $this->_subsSMS = $this->getSubsSMS();
    }
    
    abstract public function send ();
    
    private function getNormalSMS () { /* return normal sms */ }
    private function getSubsSMS () { /* return sms for subscribers */ }
}

class MTS extends Operator {
    private $_smses;
    public function __construct() {
        parent::__construct();
        $this->_smses = $this->_normalSMS + $this->_subsSMS; // control type sms
    }
    public function send () {
        // send all sms from array $this->_smses
    }
}

class Beeline extends Operator {
    private $_smses;
    public function __construct() {
        parent::__construct();
        $this->_smses = $this->_normalSMS; // control type sms
    }
    public function send () {
        // send all sms from array $this->_smses
    }
}



Sentox тоже спасибо. Там мне еще нужно читать, не все понял из того что Вы написали ... 

Это сообщение отредактировал(а) JackGmen - 1.4.2012, 23:30
PM MAIL   Вверх
baldina
Дата 2.4.2012, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(JackGmen @  1.4.2012,  21:52 Найти цитируемый пост)
abstract class Operator {
    private $_normalSMS;
    private $_subsSMS;
    
    private function __construct () {
        $this->_normalSMS = $this->getNormalSMS();
        $this->_subsSMS = $this->getSubsSMS();
    }

а как Вы будете различать к какому оператору относятся sms ?
PM MAIL   Вверх
JackGmen
Дата 2.4.2012, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(baldina @  2.4.2012,  10:05 Найти цитируемый пост)
а как Вы будете различать к какому оператору относятся sms ? 

Да, это мой втык ... спасибо ... значит нужно будет в каждом операторе выборку делать ...
PM MAIL   Вверх
baldina
Дата 2.4.2012, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(JackGmen @  2.4.2012,  10:45 Найти цитируемый пост)
значит нужно будет в каждом операторе выборку делать

может поручить это классу SMS?
просится разделение: SMS работает с данными, умея получать их для конкретного оператора, Operator только передает. 
Код

public function SMS::get ($operator_name);


Добавлено @ 11:32
Цитата(baldina @  1.4.2012,  20:22 Найти цитируемый пост)
если хотите отправлять через одного оператора все сразу, можно например так
Код

class SMServer {
  private $operators = array();
  public function __construct () {
    $this->operators[] = new MTS;
    $this->operators[] = new Beeline;
  }
  public function get ($operator) { /* return all sms from DB */  }
  public function send () {
      foreach ($this->operators as $operator)
         foreach ($this->get($operator->name) as $sms)
            $operator->send ($sms->data);
  }
}



Это сообщение отредактировал(а) baldina - 2.4.2012, 11:33
PM MAIL   Вверх
JackGmen
Дата 2.4.2012, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

SMS работает с данными, умея получать их для конкретного оператора, Operator
public function SMS::get ($operator_name);

То есть теперь в зависимости от оператора будет собираться блок смсок в самом смс сервере, никак не используя сущность оператора, что-то по моему не то с точки зрения ООП, или это нормально? или нужна еще пачка классов моделей где эти выборки блоков смс реализованы по операторам? 
PM MAIL   Вверх
ksnk
Дата 2.4.2012, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

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



Цитата(JackGmen @  1.4.2012,  18:38 Найти цитируемый пост)
 спрашиваю, если способ эту структуру сделать гибче

Абстрактной гибкости не бывает ;) Нужно придумать путь потенциального расширения системы и постараться не заткнуть.

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

Для "классовой организации" это означает, что список номеров для рассылки получается методом класса sms.
Вероятнее всего, потребуется класс `number` - хранитель номера клиента, вычислитель оператора и группы рассылки...

Это сообщение отредактировал(а) ksnk - 2.4.2012, 12:00


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
baldina
Дата 2.4.2012, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(JackGmen @  2.4.2012,  11:44 Найти цитируемый пост)
То есть теперь в зависимости от оператора будет собираться блок смсок в самом смс сервере, никак не используя сущность оператора, что-то по моему не то с точки зрения ООП, или это нормально? или нужна еще пачка классов моделей где эти выборки блоков смс реализованы по операторам

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


PM MAIL   Вверх
baldina
Дата 2.4.2012, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

посмотрите еще раз вот этот фрагмент
Код

public function send () {
      foreach ($this->operators as $operator)
         foreach ($this->get($operator->name) as $sms)
            $operator->send ($sms->data);
  }


PM MAIL   Вверх
Sentox
Дата 2.4.2012, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


как то так
**


Профиль
Группа: Участник
Сообщений: 392
Регистрация: 27.1.2009
Где: Зимбабве

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



Может будут не точности вот если нужен паттерн "observers"

user posted image

Код:
Код

abstract class Subject {

    private $observers = array();

    public $subjectsForSend = array();

    public function attachOperator(Operator $operator)
    {
        $this->observers[get_class($operator)] =  $operator;
    }

    public function detachOperator(Operator $operator)
    {
        if(isset($this->observers[get_class($operator)]))
            unset($this->observers[get_class($operator)]);
    }

    protected function notifyObservers()
    {
        foreach($this->observers as $operator)
        {
            $operator->send($this);
        }
    }

    /**
     * @param array $subjects
     */
    public function appendNewSubjects(array $subjects)
    {
        $this->subjectsForSend = $subjects;
        $this->notifyObservers();
    }
}

class SMS extends Subject {}

class MMS extends Subject {}


abstract class Operator {

    /**
     * Possible to initialize an array of several subject for send
     * @param Subject $subject
     */
    public function __construct(Subject $subject)
    {
        $subject->attachOperator($this);
    }

    /**
     * Send subject in context operators
     * @abstract
     * @param Subject $subject
     */
    abstract public function send(Subject $subject);
}

class MTC extends Operator {

    /**
     * Send subject in context operator MTC
     * @param Subject $subject
     */
    public function send(Subject $subject)
    {
        // Send subject
        if($subject instanceof SMS)
            // Send SMS
            $subject->subjectsForSend;

        if($subject instanceof MMS)
            // Send MMS
            $subject->subjectsForSend;
    }
}

class Beeline extends Operator {

    /**
     * Send subject in context operator Beeline
     * @param Subject $subject
     */
    public function send(Subject $subject)
    {
        // Send subject
        if($subject instanceof SMS)
            // Send SMS
            $subject->subjectsForSend;

        if($subject instanceof MMS)
            // Send MMS
            $subject->subjectsForSend;
    }

}

// Паттерн поведения, то есть можно добавлять и удалять "наблюдателей" операторов в динамике во время работы
// Use code
$sms = new SMS();
$MTC = new MTC($sms);
$Beeline = new Beeline($sms);

// Received SMS. Execute send in operators MTC and Beeline (observers). Send SMS for all operators.
$sms->appendNewSubjects(array('newSms' => array()));

// For send SMS from context operator append new interface (method) 
$sms->appendNewSubjectFromContext(array('exampleContext' => array()));
// Parameter from collection SMS in composition pattern 
$sms->appendNewSubjectFromContext(new SMSComposition());


Это сообщение отредактировал(а) Sentox - 2.4.2012, 22:15
PM MAIL   Вверх
JackGmen
Дата 3.4.2012, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Sentox спасибо, а в чем вы рисовали диаграмму классов?


PS я бы всем, кто здесь писал, поднял бы карму, но не могу, мало постов у меня (
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.0744 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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