Tight coupling หมายถึงคลาสและออบเจ็กต์ที่ขึ้นต่อกัน (dependent) โดยทั่วไป tight coupling มักไม่ดี เพราะลดความยืดหยุ่นและ re-usability ของโค้ด ในขณะที่ Loose coupling หมายถึงการลด dependencies ของคลาสที่ใช้คลาสอื่นโดยตรง
Tight Coupling
- Tightly coupled object คือออบเจ็กต์ที่ต้องรู้รายละเอียดของออบเจ็กต์อื่น และมักขึ้นต่อกันอย่างมากใน interfaces
- การเปลี่ยนแปลงออบเจ็กต์หนึ่งใน tightly coupled application มักต้องเปลี่ยนออบเจ็กต์อื่นๆ หลายตัว
- ในแอปพลิเคชันขนาดเล็ก เราระบุการเปลี่ยนแปลงได้ง่าย และโอกาสพลาดน้อย แต่ในแอปพลิเคชันขนาดใหญ่ ความขึ้นต่อกันเหล่านี้ไม่ได้รู้จักโดยโปรแกรมเมอร์ทุกคน และมีโอกาสมองข้ามการเปลี่ยนแปลง
ตัวอย่าง
class A {
public int a = 0;
public int getA() {
System.out.println("getA() method");
return a;
}
public void setA(int aa) {
if(!(aa > 10))
a = aa;
}
}
public class B {
public static void main(String[] args) {
A aObject = new A();
aObject.a = 100; // Not suppose to happen as defined by class A, this causes tight coupling.
System.out.println("aObject.a value is: " + aObject.a);
}
}
ในตัวอย่างข้างต้น โค้ดที่ implement แบบนี้ใช้ tight coupling และแย่มาก เนื่องจากคลาส B รู้รายละเอียดของคลาส A หากคลาส A เปลี่ยนตัวแปร 'a' เป็น private คลาส B จะพัง (break) นอกจากนี้ implementation ของคลาส A ระบุว่าตัวแปร 'a' ไม่ควรเกิน 10 แต่เราเห็นว่าไม่มีวิธีบังคับกฎนี้ได้ เนื่องจากเราสามารถเข้าถึงตัวแปรโดยตรงและเปลี่ยน state เป็นค่าไหนก็ได้
ผลลัพธ์
aObject.a value is: 100
Loose Coupling
- Loose coupling เป็นเป้าหมายการออกแบบเพื่อลด inter-dependencies ระหว่าง components ของระบบ เพื่อลดความเสี่ยงที่การเปลี่ยนแปลงใน component หนึ่งจะต้องการการเปลี่ยนแปลงใน component อื่น
- Loose coupling เป็น concept ที่ generic มากกว่า เพื่อเพิ่มความยืดหยุ่นของระบบ ทำให้ maintain ง่ายขึ้น และทำให้ framework ทั้งหมดมั่นคงขึ้น
ตัวอย่าง
class A {
private int a = 0;
public int getA() {
System.out.println("getA() method");
return a;
}
public void setA(int aa) {
if(!(aa > 10))
a = aa;
}
}
public class B {
public static void main(String[] args) {
A aObject = new A();
aObject.setA(100); // No way to set 'a' to such value as this method call will
// fail due to its enforced rule.
System.out.println("aObject value is: " + aObject.getA());
}
}
ในตัวอย่างข้างต้น โค้ดที่ implement แบบนี้ใช้ loose coupling และแนะนำ เนื่องจากคลาส B ต้องผ่านคลาส A เพื่อเข้าถึง state โดยที่กฎถูกบังคับใช้ หากคลาส A เปลี่ยนแปลงภายใน คลาส B จะไม่พัง เพราะใช้เพียงคลาส A เป็นช่องทางสื่อสาร
ผลลัพธ์
getA() method aObject value is: 0