refactoring : middle man - replace subclass with delegate
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class Booking {
|
||||
|
||||
protected Show show;
|
||||
|
||||
protected LocalDateTime time;
|
||||
|
||||
protected PremiumDelegate premiumDelegate;
|
||||
|
||||
public Booking(Show show, LocalDateTime time) {
|
||||
this.show = show;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public static Booking createBooking(Show show, LocalDateTime time) {
|
||||
return new Booking(show, time);
|
||||
}
|
||||
|
||||
public static Booking createPremiumBooking(Show show, LocalDateTime time, PremiumExtra extra) {
|
||||
Booking booking = createBooking(show, time);
|
||||
booking.premiumDelegate = new PremiumDelegate(booking, extra);
|
||||
return booking;
|
||||
}
|
||||
|
||||
public boolean hasTalkback() {
|
||||
return (this.premiumDelegate != null) ? this.premiumDelegate.hasTalkback() :
|
||||
this.show.hasOwnProperty("talkback") && !this.isPeakDay();
|
||||
}
|
||||
|
||||
protected boolean isPeakDay() {
|
||||
DayOfWeek dayOfWeek = this.time.getDayOfWeek();
|
||||
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
|
||||
}
|
||||
|
||||
public double basePrice() {
|
||||
double result = this.show.getPrice();
|
||||
if (this.isPeakDay()) result += Math.round(result * 0.15);
|
||||
return (this.premiumDelegate != null) ? this.premiumDelegate.extendBasePrice(result) : result;
|
||||
}
|
||||
|
||||
public boolean hasDinner() {
|
||||
return this.premiumDelegate != null && this.premiumDelegate.hasDinner();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate;
|
||||
|
||||
public class PremiumDelegate {
|
||||
|
||||
private Booking host;
|
||||
private PremiumExtra extra;
|
||||
|
||||
public PremiumDelegate(Booking host, PremiumExtra extra) {
|
||||
this.host = host;
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
public boolean hasTalkback() {
|
||||
return this.host.show.hasOwnProperty("talkback");
|
||||
}
|
||||
|
||||
public double extendBasePrice(double result) {
|
||||
return Math.round(result + this.extra.getPremiumFee());
|
||||
}
|
||||
|
||||
public boolean hasDinner() {
|
||||
return this.extra.hasOwnProperty("dinner") && !this.host.isPeakDay();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PremiumExtra {
|
||||
|
||||
private List<String> properties;
|
||||
|
||||
private double premiumFee;
|
||||
|
||||
public PremiumExtra(List<String> properties, double premiumFee) {
|
||||
this.properties = properties;
|
||||
this.premiumFee = premiumFee;
|
||||
}
|
||||
|
||||
public double getPremiumFee() {
|
||||
return premiumFee;
|
||||
}
|
||||
|
||||
public boolean hasOwnProperty(String property) {
|
||||
return this.properties.contains(property);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Show {
|
||||
|
||||
private List<String> properties;
|
||||
|
||||
private double price;
|
||||
|
||||
public Show(List<String> properties, double price) {
|
||||
this.properties = properties;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public boolean hasOwnProperty(String property) {
|
||||
return this.properties.contains(property);
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate._before;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class Booking {
|
||||
|
||||
protected Show show;
|
||||
|
||||
protected LocalDateTime time;
|
||||
|
||||
public Booking(Show show, LocalDateTime time) {
|
||||
this.show = show;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public boolean hasTalkback() {
|
||||
return this.show.hasOwnProperty("talkback") && !this.isPeakDay();
|
||||
}
|
||||
|
||||
protected boolean isPeakDay() {
|
||||
DayOfWeek dayOfWeek = this.time.getDayOfWeek();
|
||||
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
|
||||
}
|
||||
|
||||
public double basePrice() {
|
||||
double result = this.show.getPrice();
|
||||
if (this.isPeakDay()) result += Math.round(result * 0.15);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate._before;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class PremiumBooking extends Booking {
|
||||
|
||||
private PremiumExtra extra;
|
||||
|
||||
public PremiumBooking(Show show, LocalDateTime time, PremiumExtra extra) {
|
||||
super(show, time);
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTalkback() {
|
||||
return this.show.hasOwnProperty("talkback");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double basePrice() {
|
||||
return Math.round(super.basePrice() + this.extra.getPremiumFee());
|
||||
}
|
||||
|
||||
public boolean hasDinner() {
|
||||
return this.extra.hasOwnProperty("dinner") && !this.isPeakDay();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate._before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PremiumExtra {
|
||||
|
||||
private List<String> properties;
|
||||
|
||||
private double premiumFee;
|
||||
|
||||
public PremiumExtra(List<String> properties, double premiumFee) {
|
||||
this.properties = properties;
|
||||
this.premiumFee = premiumFee;
|
||||
}
|
||||
|
||||
public double getPremiumFee() {
|
||||
return premiumFee;
|
||||
}
|
||||
|
||||
public boolean hasOwnProperty(String property) {
|
||||
return this.properties.contains(property);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate._before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Show {
|
||||
|
||||
private List<String> properties;
|
||||
|
||||
private double price;
|
||||
|
||||
public Show(List<String> properties, double price) {
|
||||
this.properties = properties;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public boolean hasOwnProperty(String property) {
|
||||
return this.properties.contains(property);
|
||||
}
|
||||
|
||||
public double getPrice() {
|
||||
return price;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.example.refactoring._18_middle_man._40_replace_subclass_with_delegate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BookingTest {
|
||||
|
||||
@Test
|
||||
void talkback() {
|
||||
Show nonTalkbackShow = new Show(List.of(), 120);
|
||||
Show talkbackShow = new Show(List.of("talkback"), 120);
|
||||
LocalDateTime nonPeekDay = LocalDateTime.of(2022, 1, 20, 19, 0);
|
||||
LocalDateTime peekDay = LocalDateTime.of(2022, 1, 15, 19, 0);
|
||||
|
||||
assertFalse(Booking.createBooking(nonTalkbackShow, nonPeekDay).hasTalkback());
|
||||
assertTrue(Booking.createBooking(talkbackShow, nonPeekDay).hasTalkback());
|
||||
assertFalse(Booking.createBooking(talkbackShow, peekDay).hasTalkback());
|
||||
|
||||
PremiumExtra premiumExtra = new PremiumExtra(List.of(), 50);
|
||||
assertTrue(Booking.createPremiumBooking(talkbackShow, peekDay, premiumExtra).hasTalkback());
|
||||
assertFalse(Booking.createPremiumBooking(nonTalkbackShow, peekDay, premiumExtra).hasTalkback());
|
||||
}
|
||||
|
||||
@Test
|
||||
void basePrice() {
|
||||
Show lionKing = new Show(List.of(), 120);
|
||||
LocalDateTime weekday = LocalDateTime.of(2022, 1, 20, 19, 0);
|
||||
|
||||
Booking booking = Booking.createBooking(lionKing, weekday);
|
||||
assertEquals(120, booking.basePrice());
|
||||
|
||||
Booking premium = Booking.createPremiumBooking(lionKing, weekday, new PremiumExtra(List.of(), 50));
|
||||
assertEquals(170, premium.basePrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
void basePrice_on_peakDay() {
|
||||
Show lionKing = new Show(List.of(), 120);
|
||||
LocalDateTime weekend = LocalDateTime.of(2022, 1, 15, 19, 0);
|
||||
|
||||
Booking booking = Booking.createBooking(lionKing, weekend);
|
||||
assertEquals(138, booking.basePrice());
|
||||
|
||||
Booking premium = Booking.createPremiumBooking(lionKing, weekend, new PremiumExtra(List.of(), 50));
|
||||
assertEquals(188, premium.basePrice());
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasDinner() {
|
||||
Show lionKing = new Show(List.of(), 120);
|
||||
LocalDateTime weekday = LocalDateTime.of(2022, 1, 20, 19, 0);
|
||||
LocalDateTime weekend = LocalDateTime.of(2022, 1, 15, 19, 0);
|
||||
PremiumExtra premiumExtra = new PremiumExtra(List.of("dinner"), 50);
|
||||
|
||||
assertTrue(Booking.createPremiumBooking(lionKing, weekday, premiumExtra).hasDinner());
|
||||
assertFalse(Booking.createPremiumBooking(lionKing, weekend, premiumExtra).hasDinner());
|
||||
assertFalse(Booking.createBooking(lionKing, weekend).hasDinner());
|
||||
assertFalse(Booking.createBooking(lionKing, weekday).hasDinner());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user