สวัสดี! ตอนนี้เราจะเจาะลึกหัวข้อที่เป็นประโยชน์ที่สำคัญและกว้างขวางต่อไป: รูปแบบการออกแบบ วันนี้เรามาพูดถึงรูปแบบสะพานกันบ้าง เช่นเดียวกับรูปแบบอื่นๆ รูปแบบบริดจ์ทำหน้าที่แก้ปัญหาทั่วไปที่นักพัฒนาพบเมื่อออกแบบสถาปัตยกรรมซอฟต์แวร์ วันนี้เรามาศึกษาคุณสมบัติของรูปแบบนี้และหาวิธีใช้งานกัน
ที่นี่ คุณจะเห็นโครงสร้างอิสระ 2 โครงสร้างที่สามารถแก้ไขได้โดยไม่กระทบต่อฟังก์ชันการทำงานของกันและกัน ในกรณีของเรา:
รูปแบบสะพานคืออะไร?
รูปแบบสะพานเป็นรูปแบบการออกแบบโครงสร้าง กล่าวอีกนัยหนึ่ง งานหลักของมันคือการสร้างโครงสร้างที่สมบูรณ์จากคลาสและอ็อบเจกต์ สะพานทำสิ่งนี้โดยการแบ่งคลาสอย่างน้อยหนึ่งคลาสออกเป็นลำดับชั้นแยกกัน: นามธรรมและการใช้งาน การเปลี่ยนแปลงการทำงานในลำดับชั้นหนึ่งไม่ได้ทำให้เกิดการเปลี่ยนแปลงในลำดับชั้นอื่น ทั้งหมดนี้ใช้ได้และดี แต่คำจำกัดความนี้กว้างมากและไม่ได้ตอบคำถามที่สำคัญที่สุด: "รูปแบบสะพานคืออะไร" ฉันคิดว่าคุณจะเข้าใจการใช้งานจริงได้ง่ายขึ้น เอาล่ะ เรามาสร้างสถานการณ์จำลองแบบคลาสสิกสำหรับรูปแบบสะพานกัน เรามีShape
คลาสนามธรรมซึ่งแสดงถึงรูปทรงเรขาคณิตทั่วไป:
-
Shape.java
public abstract class Shape { public abstract void draw(); }
เมื่อเราตัดสินใจที่จะเพิ่มรูปทรง เช่น สามเหลี่ยมและสี่เหลี่ยม เราจะทำให้มันสืบทอด
Shape
คลาส: -
สี่เหลี่ยมผืนผ้า.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
สามเหลี่ยม.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
เมธอดจะขึ้นอยู่กับสีนี้ เพื่อให้มีการใช้งานเมธอดที่แตกต่างกันdraw()
เราจำเป็นต้องสร้างคลาสสำหรับการผสมรูปร่าง-สีแต่ละชุด ถ้าเรามี สามสี เราก็ต้องมีหกคลาส: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
และ RectangleRed
หกชั้นเรียนไม่ใช่ปัญหาใหญ่ แต่! หากเราต้องการเพิ่มรูปร่างหรือสีใหม่ จำนวนคลาสจะเพิ่มขึ้นแบบทวีคูณ จะออกจากสถานการณ์นี้ได้อย่างไร? การจัดเก็บสีในฟิลด์และระบุตัวเลือกทั้งหมดโดยใช้คำสั่งแบบมีเงื่อนไขไม่ใช่ทางออกที่ดีที่สุด วิธีแก้ไขที่ดีคือย้ายสีไปยังอินเทอร์เฟซแยกต่างหาก. ไม่พูดเร็วกว่าทำ: มาสร้างColor
อินเทอร์เฟซที่มีการใช้งานสามแบบ: BlackColor
, GreenColor
และRedColor
:
-
Color.java:
public interface Color { void fillColor(); }
-
BlackColor.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } }
-
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } }
-
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }
ตอนนี้เราเพิ่ม
Color
เขตข้อมูลในShape
ชั้นเรียน เราจะได้ค่าของมันในตัวสร้าง -
Shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
เราจะใช้
color
ตัวแปรในShape
การนำไปใช้งาน ซึ่งหมายความว่าตอนนี้รูปร่างสามารถใช้ฟังก์ชันของColor
อินเทอร์เฟซ ได้แล้ว -
สี่เหลี่ยมผืนผ้า.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color color
เป็นบริดจ์ที่เชื่อมต่อลำดับชั้นของคลาสที่แยกจากกันสองลำดับ
วิธีสร้างสะพาน: นามธรรมและการนำไปใช้
มาดูคลาสไดอะแกรมที่แสดงรูปแบบบริดจ์:
- สิ่งที่เป็นนามธรรมคือ
Shape
คลาส - RefinedAbstract คือ
Triangle
และRectangle
คลาส - Implementor คือ
Color
อินเทอร์เฟซ - ConcreteImplementor คือ
BlackColor
,GreenColor
และRedColor
คลาส
Shape
คือสิ่งที่เป็นนามธรรม — กลไกสำหรับจัดการการเติมรูปร่างด้วยสีต่างๆ ซึ่งมอบหมายให้กับColor
อินเทอร์เฟซ (Implementor) คลาสTriangle
and Rectangle
เป็นคลาสคอนกรีตที่ใช้กลไกที่Shape
คลาส มีให้ BlackColor
และGreenColor
เป็นRedColor
การนำไปใช้อย่างเป็นรูปธรรมในลำดับขั้นของการดำเนินการ
ใช้รูปแบบสะพานที่ไหน
ประโยชน์อย่างมากของการใช้รูปแบบนี้คือคุณสามารถเปลี่ยนแปลงคลาสฟังก์ชันในลำดับชั้นหนึ่งได้โดยไม่ทำลายตรรกะของอีกชั้นหนึ่ง นอกจากนี้ วิธีการนี้ช่วยลดการมีเพศสัมพันธ์ระหว่างคลาส ข้อกำหนดหลักเมื่อใช้รูปแบบนี้คือ "ทำตามคำแนะนำ" — อย่าเพิกเฉยต่อสิ่งเหล่านี้! ด้วยเหตุนี้ เรามาพิจารณาสถานการณ์ที่คุณควรใช้รูปแบบบริดจ์กัน:-
หากคุณต้องการขยายจำนวนเอนทิตีตามการรวมกันของสองแนวคิด (เช่น รูปร่างและสี)
-
หากคุณต้องการแบ่งคลาสขนาดใหญ่ที่ไม่เป็นไปตามหลักความรับผิดชอบเดียวออกเป็นคลาสขนาดเล็กที่มีฟังก์ชันการทำงานแคบ
-
หากจำเป็นต้องทำการเปลี่ยนแปลงตรรกะของเอนทิตีบางอย่างในขณะที่โปรแกรมกำลังทำงาน
-
หากจำเป็นต้องซ่อนการใช้งานจากไคลเอนต์ของคลาสหรือไลบรารี
ข้อดีข้อเสียของรูปแบบ
เช่นเดียวกับรูปแบบอื่นๆ สะพานมีทั้งข้อดีและข้อเสีย ข้อดีของรูปแบบสะพาน:- ช่วยเพิ่มความสามารถในการปรับขนาดของโค้ด — คุณสามารถเพิ่มฟังก์ชันการทำงานได้โดยไม่ต้องกลัวว่าจะเกิดความเสียหายในส่วนอื่นของโปรแกรม
- ลดจำนวนของคลาสย่อยเมื่อจำนวนของเอนทิตีจะขึ้นอยู่กับการรวมกันของสองแนวคิด (เช่น รูปร่างและสี)
- ทำให้สามารถแยกการทำงานในสองลำดับชั้นที่แยกจากกัน — Abstraction และ Implementation นักพัฒนาที่แตกต่างกัน 2 คนสามารถทำการเปลี่ยนแปลงได้โดยไม่ต้องลงลึกในรายละเอียดของโค้ดของกันและกัน
- มันลดการมีเพศสัมพันธ์ระหว่างคลาส - ที่เดียวที่ทั้งสองคลาสเชื่อมต่อกันคือสะพาน (เช่นสนาม
Color color
)
- ขึ้นอยู่กับสถานการณ์เฉพาะและโครงสร้างโดยรวมของโครงการ อาจส่งผลเสียต่อประสิทธิภาพของโปรแกรม (เช่น หากคุณต้องการเตรียมใช้งานออบเจกต์เพิ่มเติม)
- มันทำให้โค้ดอ่านได้น้อยลงเนื่องจากจำเป็นต้องสลับไปมาระหว่างสองคลาส
GO TO FULL VERSION