Skip to content

Instantly share code, notes, and snippets.

@rotelstift
Last active January 28, 2023 02:11
Show Gist options
  • Save rotelstift/33cdbb8b24948534ba573b2d7f007378 to your computer and use it in GitHub Desktop.
Save rotelstift/33cdbb8b24948534ba573b2d7f007378 to your computer and use it in GitHub Desktop.
良いコード/悪いコードで学ぶ設計入門を読み終えたらリファクタリングする予定のコード
import java.util.Random;
public class Main{
/**
* あるお店にかけられた問い合わせ電話の応対をシミュレートするコード
*
* 客からの電話にまず店員が出て質問内容を聞いて答える。
* もし自分では答えられない内容だったら店長に取り次ぐ。
*
* しかし、店長が忙しくて電話に出られない時は、
* 客の電話番号を聞いて折り返すと伝えて終了する。
* @param args
*/
public static void main(String[] args){
// 顧客、店員、店長のインスタンスを作る
Customer customer = new Customer(
new Name("Charley"),
new TelephoneNumber("00-1234-5678"),
new Inquiry()
);
Staff staff = new Staff(new Name("Alice"));
Manager manager = new Manager(new Name("Bob"));
// 電話がかかってきた
Telephone phone = new Telephone(customer, staff);
phone.callOn();
phone.call(phone.staff.askNameOf(phone.caller));
phone.call(phone.staff.askInquiryAbout(phone.caller));
if (phone.staff.canAnswer(phone.caller.inquiry)) {
phone.call(phone.staff.answer(phone.caller.inquiry));
} else if (!manager.isBusy()) {
phone = phone.takenOverReceiver(manager);
phone.call(phone.manager.helloProtocol());
phone.call(phone.manager.answer(phone.caller.inquiry));
} else {
phone.call(phone.staff.askTelephoneNumber(phone.caller));
}
phone.callOff();
return;
}
}
class Name {
final String name;
Name(final String name) {
if (name == null) {
throw new IllegalArgumentException("名前を指定してください。");
}
this.name = name;
}
}
class TelephoneNumber {
final String number;
TelephoneNumber(final String number) {
if (!number.matches("^[0-9]{2,3}-[0-9]{4}-[0-9]{4}$")) {
throw new IllegalArgumentException("電話番号が正しくありません");
}
this.number = number;
}
}
class Inquiry {
final int number;
private static final String INQUIRY_A = "閉店時間";
private static final String INQUIRY_B = "お店の場所";
private static final String INQUIRY_C = "予約できるコース";
Inquiry() {
Random randomObject = new Random();
this.number = randomObject.nextInt(3);
}
// 問い合わせ内容を答えるメソッド
String detail() {
switch(this.number) {
case 0:
return this.INQUIRY_A;
case 1:
return this.INQUIRY_B;
case 2:
return this.INQUIRY_C;
}
throw new IllegalArgumentException("問い合わせ内容が存在しません。");
}
}
class Telephone {
final Customer caller;
final People receiver;
Staff staff;
Manager manager;
Telephone(final Customer caller, People receiver) {
if (caller == null || receiver == null) {
throw new IllegalArgumentException("架電者と受電者を設定してください。");
}
this.caller = caller;
this.receiver = receiver;
if (receiver instanceof Staff) {
this.staff = new Staff(receiver.name);
} else if (receiver instanceof Manager) {
this.manager = new Manager(receiver.name);
} else {
throw new IllegalArgumentException("受電者はStaffかManagerにしてください。");
}
}
Telephone takenOverReceiver(final People receiver) {
return new Telephone(this.caller, receiver);
}
void call(final String conversations) {
System.out.print(conversations);
return;
}
void callOn() {
this.call(this.caller.helloProtocol());
this.call(this.receiver.helloProtocol());
return;
}
void callOff() {
this.call(this.caller.byeProtocol());
this.call(this.receiver.byeProtocol());
System.out.println("ガチャン(電話を切る音)");
return;
}
}
class People {
final Name name;
People(final Name name) {
this.name = name;
}
String helloProtocol() {
return this.myName() + " : もしもし?\n";
}
String byeProtocol() {
return this.myName() + " : それでは失礼します。\n";
}
String myName() {
return this.name.name;
}
}
class Customer extends People {
final TelephoneNumber telephoneNumber;
final Inquiry inquiry;
Customer(
final Name name,
final TelephoneNumber telephoneNumber,
final Inquiry inquiry
) {
super(name);
this.telephoneNumber = telephoneNumber;
this.inquiry = inquiry;
}
String answerName() {
return this.myName() + " : " + this.myName() + "です。\n";
}
String answerTelephoneNumber() {
return this.myName() + " : " + this.telephoneNumber.number + "です。\n";
}
String askingInquiry() {
return this.myName() + " : " + this.inquiry.detail() + "を伺いたいです。\n";
}
String byeProtocol() {
return this.myName() + " : ありがとうございます。それでは失礼します。\n";
}
}
class Staff extends People {
private static final String ANSWER_A = "21時です。";
private static final String ANSWER_B = "駅の東口のすぐ前です。";
Staff(final Name name) {
super(name);
}
String helloProtocol() {
return this.myName() + " : もしもし、都会の隠れ家亭です。\n";
}
String askNameOf(final Customer caller) {
String talking;
talking = this.myName() + " : お名前をお伺いしてもよろしいでしょうか?\n";
talking += caller.answerName();
return talking;
}
String askInquiryAbout(final Customer caller) {
String talking;
talking = this.myName() + " : ご用件をお聞かせください。\n";
talking += caller.askingInquiry();
return talking;
}
String askTelephoneNumber(final Customer caller) {
String talking;
talking = this.myName() + " : 調べて後ほど折り返しますので、お電話番号をお聞かせください。\n";
talking += caller.answerTelephoneNumber();
return talking;
}
Boolean canAnswer(final Inquiry inquiry) {
return(inquiry.number == 0 || inquiry.number == 1);
}
String answer(final Inquiry inquiry) {
String talking;
talking = this.myName() + " : ";
if (inquiry.number == 0) {
talking += ANSWER_A + "\n";
} else if (inquiry.number == 1) {
talking += ANSWER_B + "\n";
} else {
talking += "わかりません。\n";
}
return talking;
}
}
class Manager extends People {
private static final String ANSWER_A = "21時です。";
private static final String ANSWER_B = "駅の東口のすぐ前です。";
private static final String ANSWER_C = "春のフレンチディナーが予約できます。";
Manager(final Name name) {
super(name);
}
Boolean isBusy() {
Random randomObject = new Random();
return randomObject.nextBoolean();
}
String helloProtocol() {
return this.myName() + " : もしもし、お電話変わりました。\n";
}
String answer(final Inquiry inquiry) {
String talking;
talking = this.myName() + " : ";
if (inquiry.number == 0) {
talking += ANSWER_A + "\n";
} else if (inquiry.number == 1) {
talking += ANSWER_B + "\n";
} else if (inquiry.number == 2) {
talking += ANSWER_C + "\n";
} else {
talking += "わかりません。\n";
}
return talking;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment