В этом примере рассматривается подход к проектированию и внедрению класса. Целью этого класса является представление знакомой концепции (банковский счет). Однако к большинству проектов классов можно применить тот же подход.
Чтобы создать класс, представляющий банковский счет, сначала определите элементы данных и операции, которые формируют абстракцию банковского счета. Например, банковский счет имеет:
Номер счета
Сальдо счета
Статус (открытый, закрытый и т.д.)
Необходимо выполнить определенные операции с банковским счетом:
Создание объекта для каждого банковского счета
Внести деньги
Снять деньги
Создать инструкцию
Сохранить и загрузить BankAccount объект
Если остаток на счете слишком низок и вы пытаетесь снять деньги, банковский счет передает уведомление. Когда происходит это событие, банковский счет передает уведомление другим организациям, которые предназначены для прослушивания этих уведомлений. В этом примере эту задачу выполняет упрощенная версия программы менеджера по работе с клиентами.
В этом примере программа менеджера счетов определяет статус всех банковских счетов. Эта программа контролирует сальдо счета и присваивает одно из трех значений:
open - Сальдо счета является положительным значением
overdrawn - Остаток на счете завышен, но на 200 долларов или меньше.
closed - Остаток на счете превышен более чем на 200 долларов.
Эти функции определяют требования BankAccount и AccountManager классы. Включите только те функции, которые необходимы для достижения конкретных целей. Поддержка специальных типов счетов посредством подкласса BankAccount и добавление более специфических элементов в подклассы. Удлинить AccountManager по мере необходимости для поддержки новых типов счетов.
Классы хранят данные в свойствах, реализуют операции с методами и поддерживают уведомления с событиями и прослушивателями. Вот как BankAccount и AccountManager классы определяют эти компоненты.
Класс определяет эти свойства для хранения номера счета, сальдо счета и статуса счета:
AccountNumber - свойство для хранения номера, идентифицирующего конкретную учетную запись. MATLAB ® присваивает значение этому свойству при создании экземпляра класса. ТолькоBankAccount методы класса могут задавать это свойство. SetAccess атрибут - private.
AccountBalance - свойство для хранения текущего остатка счета. Классовая операция депонирования и вывода денег присваивает этому имуществу значения. Только BankAccount методы класса могут задавать это свойство. SetAccess атрибут - private.
AccountStatus- BankAccount класс определяет значение по умолчанию для этого свойства. AccountManager методы класса изменяют это значение всякий раз, когда значение AccountBalance опускается ниже 0. Access указывает, что только AccountManager и BankAccount классы имеют доступ к этому свойству.
AccountListener - Хранение для InsufficentFunds прослушиватель событий. Сохранение BankAccount объект не сохраняет это свойство, поскольку при загрузке объекта необходимо повторно создать прослушиватель.
Эти методы реализуют операции, определенные в формулировке класса:
BankAccount - принимает номер счета и начальное сальдо для создания объекта, представляющего счет.
deposit - Обновляет AccountBalance имущество при совершении операции по вкладу
withdraw - Обновляет AccountBalance свойство при выполнении транзакции вывода средств
getStatement - Отображение сведений об учетной записи
loadobj - воссоздает прослушиватель менеджера учетных записей при загрузке объекта из MAT-файла.
Программа менеджера по работе с клиентами изменяет статус банковских счетов с отрицательным сальдо. Чтобы осуществить это действие, BankAccount класс запускает событие, когда вывод средств приводит к отрицательному сальдо. Следовательно, инициирование InsufficientsFunds событие происходит из withdraw способ.
Чтобы определить событие, укажите имя в events блок. Инициирование события вызовом notify метод класса дескриптора. Поскольку InsufficientsFunds не является предопределенным событием, его можно назвать любым char вектор и запустить его любым действием.
BankAccount Реализация классаВажно обеспечить наличие только одного набора данных, связанных с каким-либо объектом BankAccount класс. Не требуется независимых копий объекта, которые могли бы иметь, например, различные значения для сальдо счета. Поэтому реализуйте BankAccount класс как класс дескриптора. Все копии данного объекта-дескриптора ссылаются на одни и те же данные.
BankAccount Синопсис класса
| Класс BankAccount | Обсуждение |
|---|---|
classdef BankAccount < handle
| Обрабатывать класс, так как должна быть только одна копия любого экземпляра |
properties (Access = ?AccountManager) AccountStatus = 'open' end |
|
properties (SetAccess = private) AccountNumber AccountBalance end properties (Transient) AccountListener end |
См. раздел Указание атрибутов свойств. |
events InsufficientFunds end | Класс определяет событие с именем Сведения о событиях и прослушивателях см. в разделе События. |
methods
| Блок обычных методов. Синтаксис см. в разделе Определение методов и функций классов. |
function BA = BankAccount(AccountNumber,InitialBalance) BA.AccountNumber = AccountNumber; BA.AccountBalance = InitialBalance; BA.AccountListener = AccountManager.addAccount(BA); end | Конструктор инициализирует значения свойств входными аргументами.
|
function deposit(BA,amt) BA.AccountBalance = BA.AccountBalance + amt; if BA.AccountBalance > 0 BA.AccountStatus = 'open'; end end |
Если |
function withdraw(BA,amt) if (strcmp(BA.AccountStatus,'closed')&& ... BA.AccountBalance < 0) disp(['Account ',num2str(BA.AccountNumber),... ' has been closed.']) return end newbal = BA.AccountBalance - amt; BA.AccountBalance = newbal; if newbal < 0 notify(BA,'InsufficientFunds') end end | Обновления Дополнительные сведения о прослушивателях см. в разделе Синтаксис событий и прослушивателей. |
function getStatement(BA) disp('-------------------------') disp(['Account: ',num2str(BA.AccountNumber)]) ab = sprintf('%0.2f',BA.AccountBalance); disp(['CurrentBalance: ',ab]) disp(['Account Status: ',BA.AccountStatus]) disp('-------------------------') end | Отображение выбранной информации об учетной записи. |
end methods (Static) | Конец блока обычных методов. Начало блока статических методов. См. раздел Статические методы |
function obj = loadobj(s) if isstruct(s) accNum = s.AccountNumber; initBal = s.AccountBalance; obj = BankAccount(accNum,initBal); else obj.AccountListener = AccountManager.addAccount(s); end end |
Дополнительные сведения о сохранении и загрузке объектов см. в разделе Процесс сохранения и загрузки объектов |
end end | Конец блока статических методов Конец |
AccountManager КлассЦель AccountManager класс предназначен для предоставления услуг учетным записям. Для BankAccount класс, AccountManager прослушивает вывод средств, который приводит к падению остатка в отрицательный диапазон. Когда BankAccount объект запускает InsufficientsFunds событие, AccountManager сбрасывает статус учетной записи.
AccountManager класс не сохраняет данные, поэтому ему не нужны свойства. BankAccount объект сохраняет дескриптор объекта прослушивателя.
AccountManager выполняет две операции:
Присвоение статуса каждому счету в результате снятия средств
Добавление счета в систему путем контроля сальдо счетов.
AccountManager класс реализует два метода:
assignStatus - Метод, присваивающий статус BankAccount объект. Выполняет функцию обратного вызова прослушивателя.
addAccount - Метод, который создает InsufficientFunds слушатель.
AccountManager Класс AccountManager класс реализует оба метода как статические, поскольку нет необходимости в AccountManager объект. Эти методы работают на BankAccount объекты.
AccountManager не предназначен для создания экземпляра. Разделение функциональных возможностей AccountManager класс из BankAccount класс обеспечивает большую гибкость и расширяемость. Например, это позволяет:
Удлинить AccountManager для поддержки других типов счетов, сохраняя при этом индивидуальные классы счетов простыми и специализированными.
Изменение критериев для статуса счета без влияния на совместимость сохраненных и загруженных BankAccount объекты.
Разработка Account суперкласс, определяющий то, что является общим для всех учетных записей, не требуя от каждого подкласса реализации функциональности управления учетными записями
AccountManager Синопсис класса
| Класс AccountManager | Обсуждение |
|---|---|
classdef AccountManager
| Этот класс определяет |
methods (Static)
| Нет необходимости создавать экземпляр этого класса, чтобы определенные методы были статическими. См. раздел Статические методы. |
function assignStatus(BA) if BA.AccountBalance < 0 if BA.AccountBalance < -200 BA.AccountStatus = 'closed'; else BA.AccountStatus = 'overdrawn'; end end end | |
function lh = addAccount(BA) lh = addlistener(BA, 'InsufficientFunds', ... @(src, ~)AccountManager.assignStatus(src)); end |
См. раздел Жизненный цикл прослушивателя управления |
end end |
|
BankAccount класс, хотя и слишком простой, демонстрирует, как ведут себя классы MATLAB. Например, создайте BankAccount объект с номером счета и первоначальным депозитом в размере 500 долл. США:
BA = BankAccount(1234567,500)
BA =
BankAccount with properties:
AccountNumber: 1234567
AccountBalance: 500
AccountListener: [1x1 event.listener]Используйте getStatement способ проверки состояния:
getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: 500.00 Account Status: open -------------------------
Произведите вывод 600 долл. США, что приведет к отрицательному остатку на счете:
withdraw(BA,600) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: -100.00 Account Status: overdrawn -------------------------
Вывод 600 долларов вызвал InsufficientsFunds событие. Текущие критерии, определенные классом AccountManager, приводят к состоянию overdrawn.
Произвести еще один вывод средств в размере 200 долл. США:
withdraw(BA,200) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: -300.00 Account Status: closed -------------------------
Теперь AccountStatus имеет значение closed прослушивателем и дальнейшие попытки снятия блокируются без инициирования события:
withdraw(BA,100)
Account 1234567 has been closed.
Если AccountBalance возвращается к положительному значению депозитом, затем AccountStatus возвращается к открытию, и снятие средств разрешается снова:
deposit(BA,700) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: 400.00 Account Status: open -------------------------