-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[2주차] 객체지향 코드 연습(starshape7) #1
base: main
Are you sure you want to change the base?
Changes from 6 commits
6e018ca
44f195a
957d99d
db46a76
07e3df4
cb63adc
3af2d65
f37cd84
f6b920f
c380e94
9e19af6
42db89e
bad7d99
4d876ba
11b9ddd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import java.math.BigDecimal; | ||
|
||
public class Account | ||
{ | ||
private String accountType; | ||
private String accountNum; | ||
private String owner; | ||
private BigDecimal amount; | ||
private boolean activated; | ||
|
||
public Account(String accountType, String accountNum, String owner, BigDecimal amount) | ||
{ | ||
this.accountType = accountType; | ||
this.accountNum = accountNum; | ||
this.owner = owner; | ||
this.amount = amount; | ||
this.activated = true; | ||
} | ||
|
||
public String getAccountType() {return accountType;} | ||
public void setAccountType(String accountType) {this.accountType = accountType;} | ||
public String getAccountNum() {return accountNum;} | ||
public void setAccountNum(String accountNum) {this.accountNum = accountNum;} | ||
public String getOwner() {return owner;} | ||
public void setOwner(String owner) {this.owner = owner;} | ||
public BigDecimal getAmount() {return amount;} | ||
public void setAmount(BigDecimal amount) {this.amount = amount;} | ||
public boolean isActivated() {return activated;} | ||
public void setActivated(boolean activated) {this.activated = activated;} | ||
public String getAccountInfo() | ||
{ | ||
// 계좌 정보를 문자열로 표현하여 반환 | ||
return "*************************\n" + | ||
"Owner : " + owner + "\n" + | ||
"Account Type : " + accountType + "\n" + | ||
"Account Number : " + accountNum + "\n" + | ||
"Asset : ₩" + amount + "\n" + | ||
"Activated : " + (activated ? "Yes" : "No"); | ||
} | ||
//출금 | ||
public void withdrawal(BigDecimal amount) | ||
{ | ||
if(getAmount().compareTo(amount) >= 0) | ||
{ | ||
setAmount(getAmount().subtract(amount)); | ||
System.out.println("WithDraw Finish! your Amount : ₩" + getAmount()); | ||
} | ||
else | ||
{ | ||
System.out.println("Failed WithDraw!"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 발생을 통해 처리하는 것이 좋습니다 |
||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 출금, 입금, 송금 등의 책임이 Account 객체보다는 AccountService에 있다고 보는 것이 더 좋을 것 같습니다. Account는 자신의 계좌의 출금할 만큼 돈이 있는 지 등과 같은 역할을 하는 것이 좋을 것 같습니다. 즉, 객체의 책임에 대하여 고민해보고 분리해봅시다. |
||
//입금 | ||
public void deposit(BigDecimal amount) | ||
{ | ||
setAmount(getAmount().add(amount)); | ||
System.out.println("Deposite Finish! Your Amount : ₩" + getAmount()); | ||
} | ||
//송금 | ||
public void transfer(Account receiver, BigDecimal amount) | ||
{ | ||
if(getAmount().compareTo(amount) >= 0) | ||
{ | ||
setAmount(getAmount().subtract(amount)); | ||
receiver.setAmount(getAmount().add(amount)); | ||
System.out.println("Sender : " + getOwner() + ", Receiver : " + receiver.getOwner()); | ||
System.out.println("Transfer Finish! Send ₩" + amount + " To " + receiver.getOwner()); | ||
} | ||
else | ||
{ | ||
System.out.println("Failed Transfer From" + this.getOwner() + " To " + receiver.getOwner() + " amount " + amount); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import java.math.BigDecimal; | ||
|
||
public class AccountInterestRate implements InterestCalculator | ||
{ | ||
@Override | ||
public BigDecimal getInterest(BigDecimal amount) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 한 개의 메소드에서 여러 개 책임을 갖고 있는 것 같습니다. |
||
{ | ||
BigDecimal overTenM= new BigDecimal("10000000"); // 천만 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 값을 이용하여 변수명을 짓는 것은 좋지 않습니다. |
||
BigDecimal overFiveM = new BigDecimal("5000000"); // 오백만 | ||
BigDecimal overM = new BigDecimal("1000000"); // 백만 | ||
BigDecimal overTenT = new BigDecimal("10000"); // 만 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 함수 안에서 객체를 정의하여 할당하고 있습니다. 이렇게 되면 함수를 호출할 때마다 객체가 다시 정의되어 비효율적입니다. 함수 내부가 아닌 클래스 내부에 정의하는 것이 좋아보입니다. |
||
|
||
if(amount.compareTo(overTenM) >= 0) { return new BigDecimal("0.5");} // 이자율 50% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 미리 필요한 BigDecimal 상수를 정적 변수로 선언하고 재사용하는 것이 좋습니다. 따라서 이자율은 상수로 관리하는 것이 좋아보입니다. |
||
else if(amount.compareTo(overFiveM) >= 0) { return new BigDecimal("0.07");} // 이자율 7% | ||
else if(amount.compareTo(overM) >= 0) { return new BigDecimal("0.04");} // 이자율 4% | ||
else if(amount.compareTo(overTenT) >= 0) { return new BigDecimal("0.02");} // 이자율 2% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. else if는 코드 컨벤션상 사용하지 않는 것이 좋습니다. |
||
else { return new BigDecimal("0.01");} // 이자율 1% | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,128 @@ | ||||||
import java.math.BigDecimal; | ||||||
import java.util.*; | ||||||
|
||||||
public class CentralBank | ||||||
{ | ||||||
private List<Account> accounts; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
필드에 선언하는 것이 좋을 것 같습니다. |
||||||
private Map<String, InterestCalculator> Calcualateinterest; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변수명은 카멜케이스 표기법을 사용합시다!
Suggested change
|
||||||
public CentralBank() | ||||||
{ | ||||||
accounts = new ArrayList<>(); | ||||||
Calcualateinterest = new HashMap<>(); | ||||||
Calcualateinterest.put("N", new AccountInterestRate()); | ||||||
Calcualateinterest.put("S", new SavingAccountInterestRate()); | ||||||
} | ||||||
// 게좌 만들기 | ||||||
public void createAccount(Account a) | ||||||
{ | ||||||
if(a instanceof SavingAccount) | ||||||
{ | ||||||
if(!((SavingAccount) a).compareCAGA(a)) | ||||||
{ | ||||||
accounts.add(a); | ||||||
} | ||||||
else | ||||||
{ | ||||||
System.out.println("Your Gaol Amount is smaller than your Amount"); | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
accounts.add(a); | ||||||
} | ||||||
} | ||||||
// 전체 게좌 정보 출력 | ||||||
public void printAllAccountsInfo() | ||||||
{ | ||||||
for (Account account : accounts) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for문은 java stream을 통해 최적화할 수 있습니다. 자바 스트림에 대하여 공부하여 적용해봅시다. |
||||||
{ | ||||||
System.out.println(account.getAccountInfo()); | ||||||
} | ||||||
} | ||||||
// 출금 | ||||||
public void withdrawal(String accountNum, BigDecimal amount) | ||||||
{ | ||||||
Account account = findAccountByNum(accountNum); | ||||||
if (account != null) | ||||||
{ | ||||||
account.withdrawal(amount); | ||||||
} | ||||||
else {System.out.println("Account not found!");} | ||||||
} | ||||||
// 입금 | ||||||
public void deposit(String accountNum, BigDecimal amount) | ||||||
{ | ||||||
Account account = findAccountByNum(accountNum); | ||||||
if (account != null) | ||||||
{ | ||||||
account.deposit(amount); | ||||||
} | ||||||
else | ||||||
{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. else문을 사용하지 않는 방식을 고려해봅시다. |
||||||
System.out.println("Unavailable Account"); | ||||||
} | ||||||
} | ||||||
|
||||||
// 송금 | ||||||
public void transfer(String senderAccountNum, String receiverAccountNum, BigDecimal amount) { | ||||||
|
||||||
Account sender = findAccountByNum(senderAccountNum); | ||||||
Account receiver = findAccountByNum(receiverAccountNum); | ||||||
if (sender != null && receiver != null) | ||||||
{ | ||||||
sender.transfer(receiver, amount); | ||||||
} else | ||||||
{ | ||||||
System.out.println("Sender or Receiver account not found!"); | ||||||
} | ||||||
} | ||||||
|
||||||
// 계좌번호로 계좌 찾기 | ||||||
private Account findAccountByNum(String accountNum) | ||||||
{ | ||||||
for (Account account : accounts) | ||||||
{ | ||||||
if (account.getAccountNum().equals(accountNum)) | ||||||
{ | ||||||
return account; | ||||||
} | ||||||
} | ||||||
return null; | ||||||
} | ||||||
|
||||||
// 이자를 계산하고 출력 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이자를 계산하고 / 출력... 두가지 역할을 하나의 함수에서 하고있습니다. 하나의 함수는 하나의 역할만 하도록 함수를 분리하여 단일책임원칙을 지키도록 코드를 작성해주세요 |
||||||
public void printAccountInfoNInterestRate(String accountNum) | ||||||
{ | ||||||
for (Account account : accounts) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. java stream 사용해봅시다! |
||||||
{ | ||||||
if(account.getAccountNum().equals(accountNum)) | ||||||
{ | ||||||
InterestCalculator calculator = Calcualateinterest.get(account.getAccountType()); | ||||||
BigDecimal interest = calculator.getInterest(account.getAmount()); | ||||||
System.out.println("Account Owner : " + account.getOwner() + ", Account Number: " + account.getAccountNum() + ", Interest : " + interest); | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
public void addInterest() | ||||||
{ | ||||||
if(accounts != null) | ||||||
{ | ||||||
for (Account account : accounts) | ||||||
{ | ||||||
InterestCalculator calculator = Calcualateinterest.get(account.getAccountType()); | ||||||
BigDecimal interestRate = calculator.getInterest(account.getAmount()); | ||||||
BigDecimal interestAmount = account.getAmount().multiply(interestRate); | ||||||
|
||||||
account.setAmount(account.getAmount().add(interestAmount)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. account의 amount를 추가하는 로직은 Account클래스의 책임이지 않을까요!? |
||||||
System.out.println("Finished adding Interest " + interestAmount + " to " + account.getOwner()); | ||||||
} | ||||||
System.out.println("Finished adding Interest!"); | ||||||
} | ||||||
else | ||||||
{ | ||||||
System.out.println("Accounts are not exist!"); | ||||||
} | ||||||
} | ||||||
|
||||||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 인터페이스를 사용하는 이유는 무엇일까요? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import java.math.BigDecimal; | ||
|
||
public interface InterestCalculator | ||
{ | ||
BigDecimal getInterest(BigDecimal amount); | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,161 @@ | ||||||
import java.math.BigDecimal; | ||||||
import java.util.Scanner; | ||||||
import java.util.regex.Matcher; | ||||||
import java.util.regex.Pattern; | ||||||
|
||||||
public class Main | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Main Class는 전체적인 어플리케이션을 실행시키는 역할인데, 어떤 어플리케이션인지 고민하면서 클래스 이름도 변경해보는 것도 좋을 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Main 클래스가 너무 많은 책임을 지고 있지 않나 고민해보셔야 할 것 같습니다. |
||||||
{ | ||||||
Pattern pattern = Pattern.compile("\\d{6}-\\d{2}-\\d{6}"); | ||||||
public int showMenu(Scanner s) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 화면을 출력해주는 책임을 가진 객체를 따로 분리하시는 것이 좋을 것 같습니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
외부에 드러내도 되는 메소드인가, 외부에서 사용될 메소드인가를 고민하셔서 접근제어자를 설정해야합니다. |
||||||
{ | ||||||
System.out.println("*********메뉴********"); | ||||||
System.out.println("1. 계좌 생성"); | ||||||
System.out.println("2. 인출"); | ||||||
System.out.println("3. 입금"); | ||||||
System.out.println("4. 송금"); | ||||||
System.out.println("5. 이자보기"); | ||||||
System.out.println("6. 전체 계좌 보기"); | ||||||
System.out.println("7. 각 계좌에 이자 더하기"); | ||||||
System.out.println("8. 나가기"); | ||||||
System.out.print("원하시는 작업을 선택해주세요 : "); | ||||||
return s.nextInt(); | ||||||
} | ||||||
public Account getAccount(Scanner s) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getAccount의 메소드가 단지 account를 얻는 책임만을 가지고 있는지 고민해봐야 할 것 같습니다. |
||||||
{ | ||||||
String name; | ||||||
String type; | ||||||
String aNum; | ||||||
BigDecimal amount; | ||||||
BigDecimal goalAmount; | ||||||
|
||||||
System.out.print("성명을 입력해주세요 : "); | ||||||
name = s.next(); | ||||||
|
||||||
type = getAccountType(s); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. type은 어떤 것을 의미하나요? 변수명을 좀더 구체적으로 지어주세요 |
||||||
aNum = getAccountNum(s); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aNum은 accountNumber를 의미하는 것인가요? 줄여쓰는 것은 좋지 않습니다 |
||||||
amount = getAmount(s); | ||||||
|
||||||
if(type.equals("S")) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. S가 의미하는 바는 무엇인가요? 어떤 다른 사람이 봐도 이해할 수 있게 구체적으로 작성해야 합니다. |
||||||
{ | ||||||
goalAmount = getGoalAmount(s, amount); | ||||||
return new SavingAccount(type, aNum, name, amount, goalAmount); | ||||||
} | ||||||
else {return new Account(type, aNum, name, amount);} | ||||||
|
||||||
} | ||||||
|
||||||
public String getAccountType(Scanner s) | ||||||
{ | ||||||
System.out.println("예금계좌 : N, 적금게좌 : S"); | ||||||
System.out.print("계좌 타입을 입력해주세요 : "); | ||||||
String at = s.next(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변수명을 구체적으로 작성해주세요 |
||||||
while(!at.equals("N") && !at.equals("S")) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외를 발생시켜 처리하는 것이 좋습니다 |
||||||
{ | ||||||
System.out.println("잘못된 입력값입니다."); | ||||||
System.out.print("계좌타입을 다시 입력해주세요 : "); | ||||||
at = s.next(); | ||||||
} | ||||||
return at; | ||||||
} | ||||||
|
||||||
public boolean isNumber(String s) | ||||||
{ | ||||||
try {Double.parseDouble(s);} | ||||||
catch (NumberFormatException e) | ||||||
{ | ||||||
return false; | ||||||
} | ||||||
return true; | ||||||
} | ||||||
|
||||||
public String getAccountNum(Scanner s) | ||||||
{ | ||||||
System.out.println("계좌번호를 입력하세요"); | ||||||
String an = s.next(); | ||||||
Matcher m = pattern.matcher(an); | ||||||
while(!m.matches()) | ||||||
{ | ||||||
System.out.println("잘못된 입력값입니다."); | ||||||
System.out.print("계좌번호를 다시 입력해주세요 : "); | ||||||
an = s.next(); | ||||||
m = pattern.matcher(an); | ||||||
} | ||||||
return an; | ||||||
} | ||||||
public BigDecimal getAmount(Scanner s) | ||||||
{ | ||||||
System.out.println("금액을 입력하세요"); | ||||||
String am = s.next(); | ||||||
while(!isNumber(am)) | ||||||
{ | ||||||
System.out.println("잘못된 입력값입니다."); | ||||||
System.out.print("예산을 다시 입력해주세요 : "); | ||||||
am = s.next(); | ||||||
} | ||||||
return new BigDecimal(am); | ||||||
} | ||||||
public BigDecimal getGoalAmount(Scanner s, BigDecimal current) | ||||||
{ | ||||||
System.out.println("적금 목표 금액을 입력하세요"); | ||||||
String gm = s.next(); | ||||||
while(!isNumber(gm)) | ||||||
{ | ||||||
System.out.println("잘못된 입력값입니다."); | ||||||
System.out.print("목표 금액을 다시 입력해주세요 : "); | ||||||
gm = s.next(); | ||||||
} | ||||||
return new BigDecimal(gm); | ||||||
} | ||||||
|
||||||
public String getReceiverAccountNum(Scanner s) | ||||||
{ | ||||||
System.out.println("송금하실 계좌번호를 입력하세요"); | ||||||
String an = s.next(); | ||||||
Matcher m = pattern.matcher(an); | ||||||
while(!m.matches()) | ||||||
{ | ||||||
System.out.println("잘못된 입력값입니다."); | ||||||
System.out.print("계좌번호를 다시 입력해주세요 : "); | ||||||
an = s.next(); | ||||||
m = pattern.matcher(an); | ||||||
} | ||||||
return an; | ||||||
} | ||||||
public static void main(String[] args) | ||||||
{ | ||||||
Scanner s = new Scanner(System.in); | ||||||
Main m = new Main(); | ||||||
CentralBank c = new CentralBank(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 의미있는 변수명을 사용해주세요 |
||||||
|
||||||
while(true) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 반복문 조건에 true를 명시하는 것은 위험합니다. 다른 방법을 생각해보세요 |
||||||
{ | ||||||
int i = m.showMenu(s); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기도 selectedNumber와 같이 의미있는 변수명을 가졌으면 좋겠습니다. |
||||||
switch(i) | ||||||
{ | ||||||
case 1: | ||||||
c.createAccount(m.getAccount(s)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. getAccount()가 Main의 책임인지 고민해봐야합니다 |
||||||
break; | ||||||
case 2: | ||||||
c.withdrawal(m.getAccountNum(s), m.getAmount(s)); | ||||||
break; | ||||||
case 3: | ||||||
c.deposit(m.getAccountNum(s), m.getAmount(s)); | ||||||
break; | ||||||
case 4: | ||||||
c.transfer(m.getAccountNum(s), m.getReceiverAccountNum(s), m.getAmount(s)); | ||||||
break; | ||||||
case 5: | ||||||
c.printAccountInfoNInterestRate(m.getAccountNum(s)); | ||||||
break; | ||||||
case 6: | ||||||
c.printAllAccountsInfo(); | ||||||
break; | ||||||
case 7: | ||||||
c.addInterest(); | ||||||
break; | ||||||
case 8: | ||||||
return; | ||||||
} | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코드 컨벤션에 대하여 알아보고 적용하여 읽기 쉽고 관리하기 쉬운 코드에 대해 고민해보아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://naver.github.io/hackday-conventions-java/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getter와 setter를 남발하는 것은 좋지 않습니다. 객체지향의 장점은 캡슐화에 있습니다. 즉, 외부에 객체의 구체적인 정보를 은닉하는 것에 중점을 둬야합니다. 특히 객체 내부에서 setter를 사용하고있는데 외부가 아닌 내부에서 변경되는 값인데 setter를 사용하는 이유가 무엇인가요? 접근 제어자의 역할에 대해서도 고민해봅시다.