Skip to content

Message Chains

sourcemaking

Penjelasan Smell

Smell ini terjadi ketika ingin mengakses sebuah method, perlu dilakukan pemanggilan dari hasil return method lainnya sehingga membentuk rantai: obj.a().b().c().

Perhatikan DistanceTest.java, terdapat message chaining ketika ingin mengakses latitude dan longitude.

java
class DistanceTest {
	static BojekDriver driver;
	static Destination destination;

	@BeforeAll
	static void init() {
		driver = new BojekDriver("Amir", new Position(-6.201932, 106.781529));
		destination = new Destination("Binus Anggrek", new Position(-6.201935, 106.781525));
	}

	@Test
	void manhattan() {
		DistanceCalculator calc = new Manhattan();
		double result = calc.distance(
			driver.getCurrentPosition().getLatitude(),
			driver.getCurrentPosition().getLongitude(),
			destination.getPosition().getLatitude(),
			destination.getPosition().getLongitude()
		);

		double expected = 0.000007;
		assertEquals(expected, result);
	}

	@Test
	void euclidean() {
		DistanceCalculator calc = new Euclidean();
		double result = calc.distance(
			driver.getCurrentPosition().getLatitude(),
			driver.getCurrentPosition().getLongitude(),
			destination.getPosition().getLatitude(),
			destination.getPosition().getLongitude()
		);

		double expected = 0.000005;
		assertEquals(expected, result);
	}
}
class DistanceTest {
	static BojekDriver driver;
	static Destination destination;

	@BeforeAll
	static void init() {
		driver = new BojekDriver("Amir", new Position(-6.201932, 106.781529));
		destination = new Destination("Binus Anggrek", new Position(-6.201935, 106.781525));
	}

	@Test
	void manhattan() {
		DistanceCalculator calc = new Manhattan();
		double result = calc.distance(
			driver.getCurrentPosition().getLatitude(),
			driver.getCurrentPosition().getLongitude(),
			destination.getPosition().getLatitude(),
			destination.getPosition().getLongitude()
		);

		double expected = 0.000007;
		assertEquals(expected, result);
	}

	@Test
	void euclidean() {
		DistanceCalculator calc = new Euclidean();
		double result = calc.distance(
			driver.getCurrentPosition().getLatitude(),
			driver.getCurrentPosition().getLongitude(),
			destination.getPosition().getLatitude(),
			destination.getPosition().getLongitude()
		);

		double expected = 0.000005;
		assertEquals(expected, result);
	}
}

Penyelesaian

Dilakukan Hide Delegate. Perhatikan class BojekDriver dan Destination, telah ditambahkan fungsi latitude() dan longitude() yang sebenarnya melakukan delegasi chaining yang dilakukan di package before. Hal ini dilakukan agar class client tidak merasakan adanya chaining, disembunyikan di dalam sini.

java
public class BojekDriver {
	private String name;
	private Position currentPosition;

	public BojekDriver(String name, Position currentPosition) {
		super();
		this.name = name;
		this.currentPosition = currentPosition;
	}

	public String getName() {
		return name;
	}

	public Position getCurrentPosition() {
		return currentPosition;
	}

	public double latitude() {
		return this.getCurrentPosition().getLatitude();
	}

	public double longitude() {
		return this.getCurrentPosition().getLongitude();
	}
}
public class BojekDriver {
	private String name;
	private Position currentPosition;

	public BojekDriver(String name, Position currentPosition) {
		super();
		this.name = name;
		this.currentPosition = currentPosition;
	}

	public String getName() {
		return name;
	}

	public Position getCurrentPosition() {
		return currentPosition;
	}

	public double latitude() {
		return this.getCurrentPosition().getLatitude();
	}

	public double longitude() {
		return this.getCurrentPosition().getLongitude();
	}
}

Alhasil, seperti yang bisa dilihat di DistanceTest.java di package after, message chain sudah tidak ada.

Tambahan

Jangan terlalu agresif mengurusi message chain karena bisa menyebabkan smell Middle Man.

Pertimbangkan mengurusi message chain bila terjadi di banyak tempat atau kebetulan ada class yang behavior-nya cocok untuk menampung method delegasi.

Created by Saugi