함께 작동하는 클래스 개발하기
클래스 작성하기
이 예제에서는 이벤트 및 리스너를 통해 상호 작용하는 두 클래스의 설계와 구현에 대한 접근법을 다룹니다. 두 클래스는 은행 계좌와 계좌 관리자를 나타냅니다.
은행 계좌를 나타내는 클래스를 설계하려면 먼저 데이터 요소와 은행 계좌의 추상화를 이루는 연산을 결정해야 합니다. 예를 들어, 은행 계좌에는 다음이 포함됩니다.
계좌 번호
계좌 잔고
상태(개설됨, 해지됨 등)
은행 계좌에 대해서는 다음과 같은 특정 연산을 수행해야 합니다.
각 은행 계좌에 대한 객체 생성
입금
출금
입출금 내역서 생성
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
—InsufficientFunds
이벤트 리스너에 대한 저장소입니다.BankAccount
객체를 저장해도 이 속성은 저장되지 않습니다. 그 이유는 객체를 불러올 때 리스너를 다시 생성해야 하기 때문입니다.
클래스 연산
다음 메서드는 클래스 작성 시에 정의된 연산을 구현합니다.
BankAccount
— 계좌 번호와 초기 잔고를 받아 계좌를 나타내는 객체를 생성합니다.deposit
— 입금 거래가 발생하면AccountBalance
속성을 업데이트합니다.withdraw
— 출금 거래가 발생하면AccountBalance
속성을 업데이트합니다.getStatement
— 계좌에 대한 정보를 표시합니다.loadobj
— MAT 파일에서 객체를 불러오면 계좌 관리자 리스너를 다시 생성합니다.
클래스 이벤트
계좌 관리자 프로그램은 잔고가 음수인 은행 계좌의 상태를 변경합니다. 이 동작을 구현하기 위해, 출금으로 인해 잔고가 음수가 되는 경우 BankAccount
클래스가 이벤트를 트리거합니다. 따라서, InsufficientFunds
이벤트의 트리거 동작은 withdraw
메서드 내에서 일어납니다.
이벤트를 정의하려면 events
블록 내에서 이름을 지정해야 합니다. notify
핸들 클래스 메서드에 대한 호출로 이벤트를 트리거하십시오. InsufficientFunds
는 미리 정의된 이벤트가 아니기 때문에 임의의 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 |
속성 특성(Attribute) 항목을 참조하십시오. |
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 블록의 끝입니다. |
methods (Static) | 정적 methods 블록의 시작입니다. 정적 메서드 항목을 참조하십시오. |
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 | 정적 methods 블록의 끝입니다.
|
AccountManager
클래스 작성하기
AccountManager
클래스의 용도는 계좌에 서비스를 제공하는 것입니다. BankAccount
클래스에 대해서, AccountManager
클래스는 잔고를 음수로 떨어뜨리는 출금에 대해 수신 대기합니다. BankAccount
객체가 InsufficientFunds
이벤트를 트리거하면 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
객체 사용
BankAccount
클래스는 아주 단순하지만 MATLAB 클래스의 동작을 보여줍니다. 예를 들어, 계좌 번호와 초기 입금액 500달러를 사용하여 BankAccount
객체를 생성해 보겠습니다.
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달러를 출금한 결과로, InsufficientFunds
이벤트가 트리거되었습니다. 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
가 open으로 돌아가고 출금이 다시 허용됩니다.
deposit(BA,700) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: 400.00 Account Status: open -------------------------