КОнтакты, предложения, отзывы

.rar или .zip
Вложение
Онлайн-чат
На этом сайте, вы найдёте полезную информацию, практические советы в области веб-программирования, веб-дизайна и веб-разработок в целом. Мы с удовольствием поделимся с вами реальными примерами и решениями задач, связанных с jQuery , JavaScript , PHP и MySQL , версткой сайтов , поможем разобраться новичкам с современными технологиями, такими как Ajax , HTML5 , CSS3 и многими другими.

Шаблон проектирования Facade (Фасад)

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

Проблема

Обычно в процессе проектирования системы длина ее кода, который на самом деле полезен только в пределах самой системы, постепенно увеличивается. В хорошо спроектированных системах разработчики с помощью классов определяют понятный общедоступный интерфейс и прячут поглубже внутреннее содержание системы. Но не всегда очевидно, какие части системы должны использоваться в клиентском коде, а какие лучше спрятать. Работая с такими подсистемами, как веб-форумы или приложения для создания галерей, вы, возможно, делали вызовы глубоко в логику кода. Если код подсистемы должен со временем меняться, а ваш код взаимодействует с ним в самых разных точках, то по мере развития подсистемы у вас возникнет серьезная проблема с поддержкой вашего кода. Аналогично, когда вы создаете собственные системы, имеет смысл разнести отдельные части на разные уровни. Как правило, первый уровень отвечает за логику приложения, второй - за взаимодействие с базой данных, третий - за представление данных и т.п. Вы должны стремиться поддерживать эти уровни независимыми один от другого, насколько это возможно, чтобы изменение в одной части проекта минимально отражалось на других частях. Если код одного уровня тесно интегрирован в код другого уровня, то трудно будет достичь этой цели. Приведем пример специально запутанного процедурного кода, который из простой задачи получения информации из текстовых файлов и преобразования ее в данные объекта делает что-то очень сложное.
  function getProductFileLines( $file ) {
    return file( $file );
  }

  function getProductObjectFromId( $id, $productname ) {
    // выполняем запрос к базе данных
    return new Product( $id, $productname );
  }

  function getNameFromLine( $line ) {
    if ( preg_match( "/.*-(.*)\s\d+/", $line, $array ) ) {
      return str_replace( '_',' ', $array[1] );
    }
    return '';
  }

  function getIDFromLine( $line ) {
    if ( preg_match( "/^(\d{1,3})-/", $line, $array ) ) {
      return $array[1];
    }
    return -1;
  }

  class Product {
    public $id;
    public $name;
    function __construct( $id, $name ) {
      $this->id = $id;
      $this->name = $name;
    }
  }
Давайте представим, что внутреннее содержимое этого кода сложнее, чем оно есть на самом деле, и нам приходится использовать его, вместо того чтобы переписать заново. Чтобы превратить файл
  234-женский_свитер 55
  532-мужская_шляпа 44
в массив объектов, мы должны вызвать все эти функции (ради краткости мы не извлекаем последнее число, представляющее собой цену).
  $lines = getProductFileLines ( 'test.txt' );
  $objects = array ();
  foreach ( $lines as $line ){
    $id = getIDFromLine ( $line );
    $name = getNameFromLine ( $line );
    $objects[$id] = getProductObjectFromID( $id, $name );
  }
Если мы будем вызывать эти функции непосредственно, как здесь, во всем проекте, то наш код будет плотно «вплетен» в подсистему, которую он использует. Это может стать причиной проблем, если подсистема изменится или если мы решим полностью от нее отказаться. Поэтому нам обязательно нужно создать шлюз между системой и остальным кодом.

Реализация

Приведем пример простого класса, который предоставляет интерфейс для процедурного кода, с которым мы уже встречались выше
  class ProductFacade {
    private $products = array();

    function __construct( $file ) {
      $this->file = $file;
      $this->compile();
    }

    private function compile() {
      $lines = getProductFileLines( $this->file );
      foreach ( $lines as $line ) {
          $id = getIDFromLine( $line );
          $name = getNameFromLine( $line );
          $this->products[$id] = getProductObjectFromID( $id, $name  );
      }
    }

    function getProducts() {
      return $this->products;
    }

    function getProduct( $id ) {
      if ( isset( $this->products[$id] ) ) {
          return $this->products[$id];
      }
      return null;
    }
  }
С точки зрения клиентского кода теперь доступ к объектам Product из текстового файла намного упрощен.
  $facade = new ProductFacade( 'test.txt' );
  $object = $facade->getProduct( 234 );

  print_r( $object );

Выводы

В основе шаблона Facade на самом деле лежит очень простая идея. Это всего лишь вопрос создания одной точки входа для уровня или подсистемы в целом. В результате мы получаем ряд преимуществ, поскольку отдельные части проекта отделяются одна от другой. Программистам клиентского кода полезно и удобно иметь доступ к простым методам. которые выполняют понятные и очевидные вещи. Это позволяет сократить количество ошибок, сосредоточив обращение к подсистеме в одном месте, так что изменения в этой подсистеме вызовут сбой в предсказуемом месте. Классы Facade также минимизируют ошибки в комплексных подсистемах, где клиентский код, в противном случае, мог бы некорректно использовать внутренние функции. Несмотря на простоту шаблона Facade, очень легко забыть воспользоваться им, особенно если вы знакомы с подсистемой, с которой работаете. Но, конечно, тут необходимо найти нужный баланс. С одной стороны, преимущества создания простых интерфейсов для сложных систем очевидны. С другой стороны, можно необдуманно разделить системы, а затем разделить разделения. Если вы осуществляете значительные упрощения для пользы клиентского кода и/или экранируете его от систем, которые могут изменяться. то. вероятно, есть основания для реализации шаблона Facade.
2017.08.08 218

- Чем отличается программист от политика? - Программисту платят деньги за работающие программы.
Войдите или Зарегистрируйтесь чтобы оставить комментарий

Комментарии


    Яндекс.Метрика Яндекс.Метрика