Разработка классов - типичный рабочий процесс

Формулировка класса

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

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

  • Номер счета

  • Остаток на счете

  • Состояние (открытый, закрытый, и т.д.)

Необходимо выполнить определенные операции на банковском счете:

  • Создайте объект для каждого банковского счета

  • Внесите деньги

  • Заберите деньги

  • Сгенерируйте оператор

  • Сохраните и загрузите BankAccount объект

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

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

  • open — Остаток на счете является положительным значением

  • overdrawn — Остаток на счете превышен ограничения, но на 200$ или меньше.

  • closed — Остаток на счете превышен ограничения больше чем на 200$.

Эти функции задают требования BankAccount и AccountManager классы. Включайте только, какая функциональность требуется, чтобы достигать ваших определенных целей. Поддержите специальные типы учетных записей путем разделения на подклассы BankAccount и добавление более определенных опций к подклассам. Расширьте AccountManager как требуется поддерживать новые типы учетных записей.

Определение компонентов класса

Классы хранят данные в свойствах, реализуют операции с методами и поддерживают уведомления с событиями и прослушивателями. Вот то, как BankAccount и AccountManager классы задают эти компоненты.

Данные класса

Класс задает эти свойства сохранить номер счета, остаток на счете и состояние счета:

  • AccountNumber — Свойство сохранить номер, идентифицирующий определенную учетную запись. MATLAB® присваивает значение этому свойству, когда вы создаете экземпляр класса. Только BankAccount методы класса могут установить это свойство. SetAccess атрибутом является private.

  • AccountBalance — Свойство сохранить текущий баланс учетной записи. Операция класса внесения и удаления денег присваивает значения этому свойству. Только BankAccount методы класса могут установить это свойство. SetAccess атрибутом является private.

  • AccountStatusBankAccount класс задает значение по умолчанию для этого свойства. AccountManager методы класса изменяют это значение каждый раз, когда значение AccountBalance падения ниже 0. Access атрибут задает это только AccountManager и BankAccount классы имеют доступ к этому свойству.

  • AccountListener — Устройство хранения данных для InsufficentFunds event.listener. Сохранение BankAccount объект не сохраняет это свойство, потому что необходимо воссоздать прослушиватель при загрузке объекта.

Операции класса

Эти методы реализуют операции, заданные в формулировке класса:

  • BankAccount — Принимает, что номер счета и начальный баланс создают объект, который представляет учетную запись.

  • deposit — Обновляет AccountBalance свойство, когда транзакция депозита происходит

  • withdraw — Обновляет AccountBalance свойство, когда транзакция вывода происходит

  • getStatement — Информация об отображениях об учетной записи

  • loadobj — Воссоздает прослушиватель менеджера учетных записей, когда вы загружаете объект из MAT-файла.

События класса

Программа менеджера учетных записей изменяет состояние банковских счетов, которые имеют отрицательные балансы. Реализовывать это действие, BankAccount класс инициировал событие, когда вывод приводит к отрицательному балансу. Поэтому инициирование InsufficientsFunds событие имеет место из withdraw метод.

Чтобы задать событие, задайте имя в events блок. Инициируйте событие вызовом notify метод класса Handle. Поскольку InsufficientsFunds не предопределенное событие, можно назвать его с любым char вектор и триггер это с любым действием.

BankAccount Реализация класса

Важно гарантировать, что существует только один набор данных, сопоставленных с любым объектом BankAccount класс. Вы не хотели бы независимые копии объекта, который мог иметь, например, различные значения для остатка на счете. Поэтому реализуйте BankAccount класс как класс Handle. Все копии данного объекта указателя относятся к тем же данным.

BankAccount Резюме класса

Класс BankAccountОбсуждение
classdef BankAccount < handle

Класс Handle, потому что должна быть только одна копия любого экземпляра BankAccountСравнение классов указателя и значения

   properties (Access = ?AccountManager)
        AccountStatus = 'open'
   end

AccountStatus содержит состояние учетной записи, определенной текущим балансом. Доступ ограничивается BankAccount и AccountManager классы. Доступ для членов класса

   properties (SetAccess = private)
      AccountNumber
      AccountBalance
   end
   properties (Transient)
      AccountListener
   end

AccountStatus доступ к свойству AccountManager методы класса.

AccountNumber и AccountBalance свойства имеют частный доступ к набору.

AccountListener property является переходным, таким образом, указатель прослушивателя не сохранен.

Смотрите задают Атрибуты свойств.

   events
      InsufficientFunds
   end

Класс задает событие под названием InsufficentFunds. withdraw метод инициировал событие, когда остаток на счете становится отрицательным.

Для получения информации о событиях и прослушивателях, смотрите События.

   methods

Блок обычных методов. Смотрите Задают Методы класса и Функции для синтаксиса.

      function BA = BankAccount(AccountNumber,InitialBalance)
         BA.AccountNumber = AccountNumber;
         BA.AccountBalance = InitialBalance;
         BA.AccountListener = AccountManager.addAccount(BA);
      end

Конструктор инициализирует значения свойств входными параметрами.

AccountManager.addAccount статический метод AccountManager класс. Создает прослушиватель для InsufficientFunds событие и прослушиватель хранилищ обрабатывают в AccountListener свойство.

      function deposit(BA,amt)
         BA.AccountBalance = BA.AccountBalance + amt;
         if BA.AccountBalance > 0
            BA.AccountStatus = 'open';
         end
      end

deposit настраивает значение AccountBalance свойство.

Если AccountStatus closed и последующий депозит приносит AccountBalance в положительную область значений, затем AccountStatus сбрасывается к open.

      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

Обновления AccountBalance свойство. Если значение остатка на счете отрицательно в результате вывода, notify триггеры InsufficentFunds событие.

Для получения дополнительной информации о прослушивателях смотрите Синтаксис Событий и Прослушивателей.

      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

loadobj метод:

  • Если операция загрузки перестала работать, создайте объект из a struct.

  • Воссоздает прослушиватель с помощью недавно созданного BankAccount возразите как источник.

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

   end
end

Конец блока статических методов

Конец classdef

 Расширьтесь для кода класса

Формулировка 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

Этот класс задает InsufficentFunds прослушиватель события и коллбэк прослушивателя.

   methods (Static)

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

   function assignStatus(BA)
      if BA.AccountBalance < 0
         if BA.AccountBalance < -200
            BA.AccountStatus = 'closed';
         else
            BA.AccountStatus = 'overdrawn';
         end
      end
   end

assignStatus метод является коллбэком для InsufficentFunds event.listener. Это определяет значение BankAccount объект AccountStatus свойство на основе значения AccountBalance свойство.

BankAccount конструктор класса вызывает AccountManager addAccount метод, чтобы создать и сохранить этот прослушиватель.

   function lh = addAccount(BA)
      lh = addlistener(BA, 'InsufficientFunds', ...
         @(src, ~)AccountManager.assignStatus(src));
   end

addAccount создает прослушиватель для InsufficentFunds событие, что BankAccount класс задает.

См. Управление жизненным циклом приемника

   end
end

end операторы для methods и для classdef.

 Расширьтесь для кода класса

Используя объекты BankAccount

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
-------------------------