2014-11-23 2 views
0

Я недавно изучил ООП на Java, и я пытаюсь реализовать то, что я узнал в своей пользовательской системе PHP.Должен ли объект (например, Пользователь) хранить собственные данные?

Это мой текущий класс пользователя

class User { 
    public $id; 
    public $session; 
    public $email; 
    public $lastVisit; 

    public function __construct($id) { 
     $conn = new Conn(); 
     $array = $conn->ExecuteCmdArray("SELECT * FROM user WHERE id = '".$id."'"); 
     $this->session = $array['session']; 
     $this->email = $array['email']; 
     $this->id = $array['id']; 
     $this->lastVisit = $array['last_visit']; 
    } 
} 

^О, и я должен выполнить SQL для извлечения данных?

Однако, взглянув на некоторые примеры онлайн, я просмотрел их класс User, но понял, что в нем присутствуют только такие функции, как логин и т. Д. Атрибуты в классе также являются только именем пользователя и паролем.

Должен ли он содержать все другие переменные, например пол, real_name? Мне кажется, что пользовательский класс не хранит пользовательские данные, но он используется только для входа в систему и т. Д.

Это как обычно работает пользовательский класс на PHP - что означает, что мой класс User выполнен неправильно?

+1

Этот вопрос ** НЕ ** в первую очередь на основе мнений. – Jimbo

ответ

0

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

Мы можем использовать два или более классов! В вашем примере будет минимальный класс User с минимальными атрибутами и функциями и класс Full_User, расширяющий первый.

class User { 
    public $id; 
    public $email; 
    public function __construct($array) { 
     $this->email = $array['email']; 
     $this->id = $array['id']; 
    } 
} 

class Full_User { 
    public $session; 
    public $lastVisit; 
    public function __construct($array) { 
     $this->session = $array['session']; 
     $this->lastVisit = $array['last_visit']; 
     parent::__construct($array); 
    } 
} 

Я бы предложил передать массив свойств конструктору вместо выполнения инструкции. Это позволит создавать объекты из других данных, а затем базы данных.

$id = 12; 
$conn = new Conn(); 
$minimal_array = $conn->ExecuteCmdArray("SELECT id,mail FROM user WHERE id = '".$id."'"); 
$full_array = $conn->ExecuteCmdArray("SELECT id,mail,session,lastVisit FROM user WHERE id = '".$id."'"); 
$user_for_listing = new User($minimal_array); 
$full_user = new Full_User($full_array); 
1

Ну нет правильного пути спроектировать класс пользователя. Это зависит от потребностей программистов, потребностей, навыков и понимания ООП и программного обеспечения.


разделение ответственности

О, и я должен выполнить SQL для извлечения данных?

Не рекомендуется. Хороший дизайн программного обеспечения заключается в создании разделенных автономных компонентов.

При разработке программного обеспечения это хорошая практика, чтобы придумать из коробки и поставить себя в обувь других разработчиков. Поэтому, если у вас есть объект User, не зная, что происходит за кулисами. Ожидаете ли вы, что он будет запускать Database-Queries? Нет. Ответственность за запрос базы данных не несет.

ООП также о возможности повторного использования. Если мы возьмем ваш пример: Если я брошу ваш класс User в свой собственный проект. Скорее всего, он сломается. Вы создаете соединение с базой данных непосредственно в классе. Что делать, если у меня были другие способы обработки доступа к БД? Все сломалось.

Seperation of Concerns - ключевое слово здесь. И вы должны придерживаться его всякий раз, когда это возможно.

Однако, взглянув на некоторые примеры онлайн, я просмотрел их класс User, но понял, что в нем присутствуют только функции, такие как логин и т. Д.

Задайте себе следующие вопросы:

  1. Должен ли User знает, как войти? Как его сеансы управляются или это может быть задача другого сервиса?
  2. Ожидаете ли вы, что User может войти в систему, если вы не знали этого класса?

Вы видите. Просто подумав о проблемах класса, вы можете устранить проблемы в дизайне, прежде чем они даже произойдут.

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

<?php 

$authentication = new UserAuthenticationService(); 
$authentication->attemptLogin('username', 'password'); 

if($authentication->check()) 
{ 
    $user = $authentication->getUser(); 
    echo $user->username(); 
} 

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


Это все о домене

Атрибуты в классе также только имя пользователя и пароль.

Должен ли он содержать все другие переменные, например пол, real_name? Мне кажется, что пользовательский класс не хранит пользовательские данные, но он используется только для входа в систему и т. Д.

Это зависит от вашего использования.. Если вы создаете приложение, в котором пользователи могут анонимно публиковать истории своего последнего похмелья, тогда зачем вам нужно настоящее имя?

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

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

<?php 

class User { 

    private $username; 
    private $email; 
    private $gender; 

    public function __construct($username) 
    { 
     $this->username = $username; 
    } 

    public function username() 
    { 
     return $this->username; 
    } 

    //[...] 

    public function setUsername($username) 
    { 
     $this->username = $username; 
    } 

    //[...] 

} 

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

<?php 

$authentication  = new UserAuthenticationService(); 
$persistanceMapper = new UserPersistanceMapper(); 

$authentication->attemptLogin('username', 'password'); 

if($authentication->check()) 
{ 
    // Let's rename the User just for fun 
    $user = $authentication->getUser(); 
    $user ->setName('Thomas'); 
    $persistanceMapper->persist($user); 
} 

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

  • В User способен изменить это собственное государство и может предоставить мне свои данные. Но он ничего не знает о базе данных.
  • UserPersistanceMapper знает, как сохранить пользователя (в базе данных или там, где он должен)
  • UserAuthenticationService знает, как сеанс пользователи должны быть обработаны

У меня нет на один объект, который обрабатывает все это. Вместо этого у нас есть автономные объекты, которые вместе обрабатывают наши вещи.


Это все сводится к вашим любит

Это как класс пользователя в PHP обычно работает - что означает мой класс Пользователь сделано неправильно?

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

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

Имейте в виду:

  • Попробуйте поставить себя в некоторых других разработчиков обуви при разработке приложения
  • Визуализация, как объекты связаны друг с другом перед тем вы начать кодирование
  • Пытаться держать ваши классы как можно более автономные (передайте возможные зависимости извне)
  • Получите все! Если вы не можете придумать чистый способ сделать что-то: Просто заставьте его работать. Рефакторинг вещей позже. Но убедитесь, что у вас есть периодический цикл рефакторинга . Не откладывайте вещи и не думайте: «Да ... что бы я ни делал это позже». В итоге вы получите много Code Smells.

Дальнейшее чтение

+1

Имейте +1, хотя и критикуйте: вы должны удалить установщика на 'User', потому что объект должен принуждать каждого пользователя иметь имя пользователя через его подпись конструктора. Имя пользователя должно быть 'getUsername()'. Кроме того, я не согласен с тем, что «он работает», а затем рефакторинг.Если вы делаете это в бизнесе, вы получаете устаревший код, потому что он оставлен как «просто работающий». Лучше всего думать о правильном дизайне, когда вы проходите, и учитываете его в общей оценке времени/стоимости. Кроме этого, это хороший старт. – Jimbo

+0

Эй, спасибо за чтение и за вашу критику. Да, глупый я, вы абсолютно правы в настройке имени пользователя в конструкторе. О префиксе 'get'. Думаю, это касается предпочтений. Технически 'getUsername()' было бы лучше здесь, но с семантической точки зрения мне больше нравится без префикса. – thpl

+0

О рефакторинге: то, что я имел в виду, заключается в том, что нужно повторить итерации. Вы пишете плохой код? Вы положили его на свой todo и на следующий цикл рефакторинга, который вы исправили. Я не хотел говорить, что нужно просто написать неряшливый код и сказать: «Да, я сделаю это позже ... или никогда». Я уточню, что немного больше. Thanks @Jimbo – thpl

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