web - tec / PHP 5 для начинающи
.pdf
|
|
|
|
Работа с UML и классами 525 |
||
|
|
|
|
|
|
|
|
Address |
|
|
PhoneNumber |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Entity
|
|
|
|
|
|
|
|
|
|
|
|
Individual |
|
|
Organization |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 13.6.
Теперь ясно, что классы Individual и Organization наследуют класс Entity. Использование соединительных линий для обозначения наследования позволяет лег+ ко при беглом осмотре диаграммы понять, какие классы связаны друг с другом.
Часто приходится показывать другой тип соединения: класс Entity использует классы Address, Email и PhoneNumber. В UML+спецификации такая взаимосвязь на+ зывается агрегированием (aggregation) и обозначается с помощью черного ромбика на том конце линии, который присоединен к классу+пользователю (рис. 13.7). Исполь+ зуемые классы имеют свойство множественность (multiplicity), которое пока+ зывает, сколько раз они используются. В этом примере в классе Entity может при+ сутствовать один или несколько типов контактов, либо не быть ни одного. Для того чтобы обозначить это, над соединительной линией ближе к используемому классу не+ обходимо написать 0..*, чтобы показать, что класс может иметь 0 или больше указы+ вающих на него классов. Это обозначение показано на рис. 13.7. Увидев такую связь, разработчик может ясно представить, на какие части приложения повлияет измене+ ние того или иного класса. В данном случае изменение в классе Email, Address или
PhoneNumber повлияет на классы Entity, Individual и Organization.
Работа с UML и классами 527
Начало регистрации
Пользователь выбирает проект
Проект имеет |
Да |
Пользователь |
Да |
ограничения? |
|
имеет ограничения? |
|
Нет |
|
Нет |
|
Пользователь может |
|
|
Пользователь не может |
зарегистрироваться |
|
|
зарегистрироваться |
Рис. 13.8.
Эта диаграмма показывает, где принимаются решения (ромбики), необходимые действия (прямоугольники), а также начальное и конечное состояния (эллипсы) про+ цесса. При написании комплексного кода с условной логикой рекомендуется создать диаграмму действий для планирования и документирования кода.
Диаграммы ситуаций
Диаграмма ситуаций (use case diagram) иллюстрирует бизнес+процессы и их поль+ зователей. Это нетехническая диаграмма, она способствует пониманию задач при пе+ реговорах с клиентами.
В диаграммах ситуаций используется два базовых обозначения: актор (пользователь процесса) и ситуация (процесс). Актором обычно является класс пользователей при+ ложения. Например, крупный Web+сайт, как правило, содержит общедоступную об+ ласть и систему администрирования, которая позволяет определенным пользовате+ лям манипулировать содержимым сайта. В таком случае имеется два актора: администратор и пользователь. Администраторы изменяют и просматривают содер+ жимое сайта и создают различные отчеты. Пользователи только просматривают со+ держимое. На рис. 13.9 показана соответствующая диаграмма ситуаций.
На диаграмме представлены два актора, три ситуации и указатели на то, какие ак+ торы участвуют в той или иной ситуации. Такие диаграммы помогают понять роли и ответственность в приложении и перечислить бизнес+процессы, которые будет поддерживать приложение.
Диаграмма последовательностей
Диаграмма последовательностей (sequence diagram) показывает порядок опера+ ций для определенного процесса в приложении. Горизонтальная ось представляет жизненный цикл задействованных в процессе объектов, а вертикальная ось ++++++ поря+ док операций (первая операция находится вверху). Диаграмма такого типа показывает
Работа с UML и классами 529
Диаграмма последовательностей упрощает планирование информационного об+ мена между объектами и документирует этапы выполнения заданного действия.
Приведенные выше примеры показывают, какими полезными могут быть UML+ диаграммы при проектировании приложения. Используя общий визуальный язык для представления различных понятий в программной системе, можно в доступной для по+ нимания форме передавать сложные идеи и документировать замысловатые процес+ сы. Стандартизация используемых обозначений гарантирует, что другие разработчи+ ки программного обеспечения смогут понять диаграммы и использовать их для создания описанного ими приложения.
Создание класса Entity
Теперь можно применить все полученные ранее знания для создания спроектиро+ ванного выше приложения ++++++ диспетчера контактов. Приложение предназначено для управления информацией о частных лицах и организациях и предоставляет пользо+ вателям возможность просматривать и редактировать контактную информацию. На рис. 13.11 показана UML+диаграмма диспетчера контактов.
Address
PhoneNumber
Entity
|
|
|
|
|
|
|
|
|
|
|
|
Individual |
|
|
Organization |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 13.11.
Класс Entity довольно понятен. Он должен хранить имя и идентификатор объек+ та наряду с массивами почтовых и e+mail+адресов и телефонных номеров. Этот класс не будет использоваться непосредственно. Он будет родительским классом для классов
530 Глава 13
Individual и Organization. Класс User, созданный в главе 12, хорошо подходит в качестве основы для класса Entity.
Создайте новый текстовый файл с именем class.Entity.php и введите в него следующий код, большая часть которого взята из класса User (хотя есть несколько важных изменений). Несмотря на то что этот пример кода довольно большой, он дос+ таточно прост. Полное объяснение класса приведено сразу после кода.
<?php
class Entity {
private $_properties; private $_changedProperties; private $_hDB;
private $_emails; private $_addresses; private $_phonenumbers;
public function __construct($entityID)
{
$this->_properties = array(); $this->_changedProperties = array();
$this->_properties['id'] = $entityID; $this->_properties['name'] = null; $this->_properties['type'] = null; $this->_properties['addresses'] = array(); $this->_properties['phonenumbers'] = array(); $this->_properties['emails'] = array(); $this->_properties['numberOfEmails'] = 0; $this->_properties['numberOfPhonenumbers'] = 0; $this->_properties['numberOfAddresses'] = 0;
$this->_hDB = mysql_connect('localhost', 'dbuser', 'mypassword');
$this->_init();
}
private function _init()
{
$this->_initUser(); $this->_initEmails(); $this->_initAddresses(); $this->_initPhones();
}
private function _initUser()
{
$sql = "select * from entities where entityid = $this->id";
$rs = mysql_query($sql, $this->_hDB); $row = mysql_fetch_assoc($rs);
$this->_properties['id'] = $row['entityid']; $this->_properties['name1'] = $row['name1']; $this->_properties['name2'] = $row['name2']; $this->_properties['type'] = $row['type'];
}
private function _initEmails()
Работа с UML и классами 531
{
//выбрать e-mail-данные...
}
private function _initPhones()
{
//выбрать данные о телефонах...
}
private function _initAddresses()
{
//выбрать данные по адресам...
}
function __get($propertyName)
{
if(!array_key_exists($propertyName, $this->_properties)){ throw new Exception('Неправильное значение свойства!');
}
}
if(method_exists($this, 'get' . $propertyName)){
return call_user_func(array($this, 'get' . $propertyName)); } else {
return $this->_properties[$propertyName];
}
} |
|
function __set($propertyName, $value) |
{ |
if(!array_key_exists($propertyName, $this->_properties)){ throw new Exception('Неправильное значение свойства!');
}
}
if(method_exists($this, 'set' . $propertyName))
{
return call_user_func(array($this, 'set' . $propertyName), $value);
} else {
//Если значение свойства действительно было изменено, //но еще не попало в массив changedProperties,
//то добавить его в этот массив. if($this->_properties[$propertyName] != $value && !in_array($propertyName, $this->_changedProperties)) {
$this->_changedProperties[] = $propertyName;
}
//Устанавливаем новое значение свойства $this->_properties[$propertyName] = $value;
}
}
function __toString()
{
return $this->name;
}
function getName()
{
return $this->_properties['name1'];
}
function setID($val)
{