Проблема объектно-ориентированного дизайна - PullRequest
4 голосов
/ 16 декабря 2009

Я проектировал сайт локально в PHP 5, но столкнулся с несколькими проблемами дизайна, которые я хотел бы получить сейчас.

В настоящее время на сайте есть три функции, и у каждой функции есть свой класс. Эти функции следующие:

  • блог
  • список друзей
  • набор изображений

У меня есть класс для каждого, но в каждом классе я в основном определяю похожий метод, который получает все [блоги | Друзья | изображений]. Мне было интересно, знает ли кто-нибудь из вас, как я могу уменьшить эти классы, чтобы они стали намного тоньше и, вероятно, имели бы один класс, который является общим для всех трех функций для всех методов, одинаковых для каждой функции. (т.е. getAllById ($ feature, $ id)).

Пример функции для моего существующего класса блога выглядит следующим образом:

function getBlogsByUserId($userId) {
    global $db;
    $blogs = array();
    $db->where(array("userId"=>$userId));
    $rows = $db->get("blog")->fetch(0);
    foreach($rows as $row) {
 $blog = new Blog();
 $blog->id = $row['id'];
 $blog->userId = $row['userId'];
 $blog->content = $row['content'];
 $blogs[] = $blog;
    }
return $blogs;
}

Примечание: я определил свой собственный класс для БД, так что не беспокойтесь об этом.

Я посмотрел шаблон проектирования шлюза, но пока не нашел решения. Я также хочу, чтобы это можно было использовать повторно, поэтому если я увеличу количество функций до семи или более, мне не придется менять большую часть класса.

Спасибо, Matt

Ответы [ 3 ]

1 голос
/ 16 декабря 2009

Вы можете создать родительский класс с именем, скажем, Model, например:

abstract class Model {
  protected static $_featureTable;

  static public function getAllById($id) {
    global $db;
    $items = array();
    $db->where(array("userId"=>$userId));
    $rows = $db->get(self::$_featureTable)->fetch(0);
    foreach($rows as $row) {
      $item = self::getInstance();
      $item->setValues($row);
      $items[] = $item;
    }
    return $items;
  }

  abstract static protected function getInstance();
  abstract protected function setValues($row);
}

class Blog extends Model {
  protected static $_featureTable = 'blogs';

  protected static function getInstance() {
    $self = __CLASS__;
    return new $self();
  }

  protected function setValues($row) {
    $this->content = $row['content'];
    // etc.
  }
}

Затем, чтобы получить список блогов:

$blogs = Blog::getAllById($id);
1 голос
/ 16 декабря 2009

Может быть, вам стоит взглянуть на некоторые ORM системы, такие как Doctrine или Propel . Это очень поможет вам в сопоставлении вашей базы данных <->.

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

0 голосов
/ 16 декабря 2009

Вы можете создать параметрируемый объект / функцию Factory. Это объединит функцию 'row_to_object' и объект 'query':

function row_to_blog( $row ) {
    return new Blog( $row["id"], $row["title"] );
}

function create_from_query( $query, $row_to_object ) {
    $objects=array();
    foreach( $row as $db->fetch( $query ) ) {
       $objects[]=$row_to_object( $row );
    }
    return $objects;
}

$query=new Query( "blogs", new Where("userid",$id) );
$blogs=create_from_query( $query, row_to_blog );
...