-
Notifications
You must be signed in to change notification settings - Fork 0
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
[14주차] 11. API 리팩터링 (~11.6) #13
Labels
Comments
11.1 질의 함수와 변경 함수 분리하기겉보기 부수효과가 전혀 없이 값을 반환해주는 함수를 추구해야 한다. 명령과 질의를 분리한다. 11.2 함수 매개변수화하기함수의 로직이 아주 비슷하고 리터럴 값만 다르다면, 매개변수로 받아 처리하는 함수 하나로 처리 11.3 플래그 인수 제거하기플래스 인수가 있으면 함수들의 기능 차이가 잘 드러나지 않는다. 사용할 함수를 선택한 후에도 플래그 인수로 어떤 값을 넘겨야 하는지를 또 알아내야 한다. 플래그 인수를 싫어하는 이유는 불리언 값을 데이터가 아닌 리터럴로 설정하기 때문 11.4 객체 통째로 넘기기레코드를 통째로 넘기면 변화에 대응하기 쉽다. 11.5 매개변수를 질의 함수로 바꾸기매개변수를 건넬 필요가 없이 필요할 때 직접 호출가능하다면 바꾼다. 11.6 질의 함수를 매개변수로 바꾸기참조 투명성 - 같은 인풋에 같은 아웃풋을 배출 의존성을 모듈 바깥으로밀어낸다 - 책임을 호출자에게 지운다. |
11.1코드 보기fun setOffAlarms() {
}
fun findMiscreant(people: List<People>): String {
for (p: People in people) {
if (p.name == "조커") {
return "조커"
}
if (p.name == "사루만") {
return "사루만"
}
}
return ""
}
fun alertForMiscreant(people: List<People>) {
for (p: People in people) {
if (p.name == "조커") {
setOffAlarms()
return
}
if (p.name == "사루만") {
setOffAlarms()
return
}
}
return
}
fun main() {
val people = listOf(People("조커"), People("테스트"), People("사루만"))
alertForMiscreant(people)
} 11.2코드 보기fun usd(number: Int): String {
return NumberFormat.getCurrencyInstance(Locale.US).format(number / 100)
}
fun usd(number: Double): String {
return NumberFormat.getCurrencyInstance(Locale.US).format(number / 100)
}
fun withBand(usage: Long, bottom: Long, top: Long): Long {
return if (usage > bottom) {
usage.coerceAtMost(top) - bottom
} else {
0
}
}
fun withBand(usage: Long, bottom: Long, top: Double): Long {
return if (usage > bottom) {
usage.coerceAtMost(top.toLong()) - bottom
} else {
0
}
}
fun baseCharge(usage: Long): String {
if (usage < 0) return usd(0)
val amount =
withBand(usage, 0, 100) * 0.03
+withBand(usage, 100, 200) * 0.05
+withBand(usage, 200, Infinity) * 0.07
return usd(amount)
} 11.3코드 보기fun bookConcert(aCustomer: Any, isPremium: Boolean) {
if (isPremium) {
// 프리미엄 예약용 로직
} else {
// 일반 예약용직로직
}
}
// 아래와 같이 로직 수정
fun premiumBookConcert(aCustomer: Any) {
} 11.4코드 보기fun main() {
val daysTempRange = TempRange(10, 50)
val aRoom = Room(daysTempRange)
val low = aRoom.daysTempRange.low
val high = aRoom.daysTempRange.high
val aHeatingPlan = HeatingPlan(daysTempRange)
if (!aHeatingPlan.withRange(aRoom.daysTempRange)) {
println("방 온도가 지정 범위를 벗어났습니다")
}
} 11.5코드 보기// 매개변수를 질의 함수로 바꾸기
class Order(
val quantity: Long,
val itemPrice: Long,
) {
fun finalPrice(): Double {
val basePrice = this.quantity * this.itemPrice
return this.discountedPrice(basePrice)
}
private fun discountedPrice(basePrice: Long): Double {
return when (discountLevel()) {
1L -> basePrice * 0.95
2L -> basePrice * 0.9
else -> 0.0
}
}
private fun discountLevel(): Long {
return if (this.quantity > 100) {
2L
} else {
1L
}
}
} 11.6코드 보기// 11.6 질의 함수를 매개변수로 바꾸기
// 11.5의 리팩터링과 반대의 리팩터링이다.
// 그러나 저자는 이 리팩터링 보다는 호출자가 단순해지는 11.5의 리팩토링을 더 선호한다고 밝혔다.
// 여기서 이 리팩토링을 하는 이유는 함수 내에서 전역 변수를 사용하면서 참조 투명성을 잃게 되는 문제를 해결하기 위함이다.
// Thermostat : 온도 조절기
class Thermostat(
val selectedTemperature: Long,
val currentTemperature: Long,
)
val thermostat: Thermostat = Thermostat(20, 30)
class HeatingPlan(
val max: Long,
val min: Long,
) {
fun targetTemperature(selectedTemperature: Long): Long {
return if (selectedTemperature > this.max) this.max
else if (selectedTemperature < this.min) this.min
else selectedTemperature
}
}
fun main() {
val thePlan = HeatingPlan(50, 10)
if (thePlan.targetTemperature(thermostat.selectedTemperature) > thermostat.currentTemperature) {
setToHeat()
} else if (thePlan.targetTemperature(thermostat.selectedTemperature) < thermostat.currentTemperature) {
setToCool()
} else {
setOff()
}
}
fun setOff() {
TODO("Not yet implemented")
}
fun setToCool() {
TODO("Not yet implemented")
}
fun setToHeat() {
TODO("Not yet implemented")
}
|
11.1 질의 함수와 변경 함수 분리하기// before
public long getTotalOutstandingAndSendBill() {
long result = customer.getInvoices()
.stream()
.mapToLong(Invoice::getAmount)
.sum();
emailGateway.send(formatBill(customer));
return result
}
// after
public long getTotalOutstanding() {
return customer.getInvoices()
.stream()
.mapToLong(Invoice::getAmount)
.sum();
}
public void sendBill() {
emailGateway.send(formatBill(customer));
}
11.2 매개 변수화하기// before
public void raiseSalaryTenPercent() {
this.salary = this.salary.multiply(1.1);
}
public void raiseSalaryFivePercent() {
this.salary = this.salary.multiply(1.05);
}
// after
public void raiseSalary(double factor) {
this.salary = this.salary.multiply(factor);
}
11.3 플래그 인수 제거하기// before
public void setDimension(String name, double value) {
if (name.equals("height")) {
this.height = value;
return;
}
if (name.equals("width")) {
this.width = value;
return;
}
}
// after
public void setHeight(double value) {
this.height = value;
}
public void setWidth(double value) {
this.width = value;
}
11.4 객체 통째로 넘기기// before
double low = room.getDaysTempRange().getLow();
double high = room.getDaysTempRange().getHigh();
if (plain.withinRange(low, high))
// after
if (plain.withinRange(room.getDaysTempRange()))
11.5 매개변수를 질의 함수로 바꾸기// before
availableVacation(employee, employee.getGrade());
public boolean availableVacation(Employee employee, Grade grade) {...}
// after
availableVacation(employee);
public boolean availableVacation(Employee employee) {
Grade grade = employee.getGrade(); // 매개변수를 질의함수로 바꾼 부분
...
}
11.6 질의 함수를 매개변수로 바꾸기
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
진도
방식
The text was updated successfully, but these errors were encountered: