2010-04-12 2 views
4

Я знаю, что в ООП вы хотите, чтобы каждый объект (из класса) был «вещью», например. пользователь, валидатор и т. д.Как правильно моделировать модели: объектно-ориентированный или «пакетный» -ориентированный?

Я знаю основы о MVC, как они взаимодействуют друг с другом.

Однако мне интересно, должны ли модели в MVC быть спроектированы в соответствии с традиционным дизайном ООП, т. Е. Каждая модель должна быть базой/таблицей/строкой (решение 2)?

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

пример для модуля адресной книги в CodeIgniter, где я хочу иметь возможность «CRUD» связаться и добавить/удалить его в/из контактной группы, имеющей CRUD.

Модели раствор 1: гармошки все связанные с ним методы вместе (не реальный объект, а скорее "пакет")

class Contacts extends Model { 

    function create_contact() {) 
    function read_contact() {} 
    function update_contact() {} 
    function delete_contact() {} 

    function add_contact_to_group() {} 
    function delete_contact_from_group() {} 

    function create_group() {} 
    function read_group() {} 
    function update_group() {} 
    function delete_group() {} 

} 

Модели решения 2: ООП путь (один класс для каждого файла)

class Contact extends Model { 
    private $name = ''; 
    private $id = ''; 

    function create_contact() {) 
    function read_contact() {} 
    function update_contact() {} 
    function delete_contact() {} 

} 

class ContactGroup extends Model { 
    private $name = ''; 
    private $id = ''; 

    function add_contact_to_group() {} 
    function delete_contact_from_group() {} 

    function create_group() {} 
    function read_group() {} 
    function update_group() {} 
    function delete_group() {} 

} 

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

решение 2 работает в соответствии с ООП. но я не знаю, почему я должен сделать такое разделение. какие преимущества будут иметь, например, контактный объект. Это, безусловно, не объект User, так почему бы Contact «жить» со своим собственным состоянием (свойствами и методами). Потому что я склонен думать так: если что-то нуждается в состоянии, тогда я создаю класс ООП, чтобы методы могли влиять на состояние или другие вещи, основанные на состоянии.

так что модели должны быть "stateful" тоже? если они не требуют состояния, почему я должен создать его в соответствии с шаблоном ООП. то я мог бы просто собрать все вместе, как «пакетное» решение.

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

EDIT: задумайтесь о контроллерах в MVC. они создаются в соответствии с решением «пакет». Это заставляет меня задаться вопросом ...

ответ

2

должна ли каждая модель быть база данных/таблица/строка (решение 2)?

Нет. Не привязывайте определение модели к ее методу сохранения. Хотя для простых приложений вы можете расширить модель из объекта строки базы данных, вы должны держать их по крайней мере мысленно разделенными.

Модели - это просто представления объектов в вашем домене, поэтому по необходимости они имеют состояние. Где вы говорите о модели Contact, вы действительно говорите о картере или шлюзе, т. Е. О том, как объект извлекает вашу модель из хранилища данных. К сожалению, так много специальных внедрений Active Record загрязнили воды на этом.

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

Модель сама по себе должна быть просто набором данных, либо хранимых в качестве общедоступных свойств, либо предпочтительно с соответствующими установщиками и геттерами (пожалуйста, не просто определяйте пара функций get/set для каждой переменной, либо вы можете также просто оставьте их общедоступными), а также другие методы, которые работают с данными. Он не должен иметь никакого представления о хранилище данных или зависимости от него. Ответственность за создание и инициализацию модели через интерфейс пользователя несет разработчик. Это позволит обеспечить гибкость в том, как вы можете создавать и сохранять свои модели. Вы можете сделать это из базы данных, XML-файла, внутри-кода, из сериализованного потока, отправляемого по сети, независимо от того, что плавает ваша лодка действительно, заменяя другой картограф, и модель остается полностью не осознанной.

+0

Я думаю, что получаю вашу мысль. но является ли код sql для извлечения/вставки строк из/в базу данных в mapper_model или data_models?почему я должен получать данные из mysql и помещать их в data_model (каждый объект, представляющий контакт) через карту? в чем смысл? или я неправильно понял поток? CONTROLLER вызывает MAPPER_MODEL, который извлекает данные из MYSQL и помещает их в DATA_MODEL? Я думаю, что ошибаюсь. не могли бы вы объяснить поток для меня. –

+0

У вас все в порядке. Контроллер вызывает отображение (обычно косвенно через службу или ссылаясь на другую модель в зависимости от того, как далеко вы хотите что-то делать) и запрашивает модель. Mapper создает модель, заполняет ее и возвращает ее. Целью является абстракция; он защищает модель от изменений в хранилище данных. Код MySQL принадлежит картографу, модель не должна знать об этом. Если вы решили сохранить ваши данные в другом формате позже, скажем, XML, тогда вы напишите картограф, который анализирует XML-файлы и возвращает модель. Таким образом, вся логика персистентности инкапсулируется. – Duncan

+0

это имеет для меня такой смысл! поэтому в основном я должен назвать своих картографов на любом уровне данных, который они используют, например. «xml_mapper_model», «mysql_mapper_model». таким образом, я мог бы использовать любое хранилище данных, которое я предпочитаю. и модели данных являются «contact_model» и «contact_group_model». это как матрица. Всякая программа - это «человеческая душа», ответственная только за одну задачу. мы получили «привратника», «ключевого производителя», «охранников» и т. д. поэтому целое приложение - это всего лишь куча этих объектов, связанных с/делегированием задач друг другу. также как военное правительство =) –

2

Я не знаю, если есть лучший способ, но я поделюсь, как я это сделать ...

У меня есть шлюз таблицы, например, ContactTableGateway, который содержит все sql для работы с контактами. Мне нравится, что все sql находятся в одном месте.

class ContactTableGateway extends Model { 

    function saveContact(Contact $contact) 
    function getContact ($contact_id) 
    function createContact (Contact $contact) 

} 

Тогда у меня есть контактный класс, который в основном имеет только получатели и сеттеры (или общедоступные свойства).Объекты этого класса используются в качестве аргументов для шлюза таблицы для сохранения/создания

class Contact extends Model { 

    function getName() 
    function getAddress() 
    function getEmail() 
    .... 

} 

Heres упрощенного примера

if (isset($_POST)) { 

    // some validation here 
    $contact = new Contact; 
    $contact->name = $_POST['name']; 
    $contact->email = $_POST['email'] 
    $contactTableGateway = new ContactTableGateway; 

    if ($contactTableGateway->createContact($contact)) { 
     echo "YAY"; 
    } 
} 
+0

Благодарим за обмен! это похоже на то, что вы идете с решением ООП :) и выглядит довольно элегантно. как насчет ваших контроллеров, они больше похожи на пакеты или объектно-ориентированные? –

+0

Я не уверен, что вы имеете в виду. site.com/contact/create = создать метод на контроллере контакта. site.com/contact/view/3/ = метод просмотра на контроллере контакта, просмотр контакта с идентификатором: 3 – Galen

+0

о, не обращайте внимания на контроллеры :), вы получили публичные свойства в классе контактов? причина в том, что доступ к ним невозможен. но я никогда не хочу, чтобы мои свойства были доступны напрямую, но были закрыты, поэтому к ним можно было получить доступ только через сеттеры/геттеры. осложнение. –

1

Я думаю, ваше решение # 2 превосходят как это больше молекулярных/модульное, поэтому , более понятным, гибким и расширяемым (в домене ООП). Он также более удобен для ресурсов, так как он может позволить вам загружать только класс Contact, если нет необходимости в функциональности группы контактов и наоборот. Это преимущество разделения.

Если модели не нуждаются в состоянии, это не означает, что OOP/MVC не применяется. Модели таблиц могут не иметь состояния в дизайне, но поэтому у нас есть статические методы/члены, т. Е. Contact :: read ($ id).

Смежные вопросы