เราได้ตรวจสอบการใช้งานของ singleton object แล้ว แต่คุณอาจยังไม่ทราบว่ากลยุทธ์นี้เป็นรูปแบบการออกแบบและเป็นหนึ่งในรูปแบบที่ใช้มากที่สุด
อันที่จริงมีรูปแบบเหล่านี้มากมายและสามารถจำแนกตามวัตถุประสงค์เฉพาะได้
การจำแนกรูปแบบ
ประเภทรูปแบบ | แอปพลิเคชัน |
---|---|
สร้างสรรค์ | ประเภทที่แก้ปัญหาการสร้างวัตถุ |
โครงสร้าง | รูปแบบที่ช่วยให้เราสร้างลำดับชั้นที่ถูกต้องและขยายได้ในสถาปัตยกรรมของเรา |
พฤติกรรม | กลุ่มของรูปแบบนี้อำนวยความสะดวกในการโต้ตอบอย่างปลอดภัยและสะดวกระหว่างวัตถุในโปรแกรม |
โดยทั่วไปแล้ว รูปแบบจะมีลักษณะตามปัญหาที่แก้ได้ มาดูรูปแบบบางส่วนที่เราพบบ่อยที่สุดเมื่อทำงานกับ Java:
ลวดลาย | วัตถุประสงค์ |
---|---|
ซิงเกิ้ลตัน | เราคุ้นเคยกับรูปแบบนี้อยู่แล้ว — เราใช้เพื่อสร้างและเข้าถึงคลาสที่ไม่สามารถมีมากกว่าหนึ่งอินสแตนซ์ |
วนซ้ำ | เรายังคุ้นเคยกับสิ่งนี้ เราทราบดีว่ารูปแบบนี้ช่วยให้เราวนซ้ำวัตถุคอลเลกชันโดยไม่ต้องเปิดเผยการเป็นตัวแทนภายใน ใช้กับของสะสม |
อแดปเตอร์ | รูปแบบนี้เชื่อมต่อวัตถุที่เข้ากันไม่ได้เพื่อให้สามารถทำงานร่วมกันได้ ฉันคิดว่าชื่อของรูปแบบอะแดปเตอร์ช่วยให้คุณนึกภาพออกว่ามันใช้ทำอะไร นี่คือตัวอย่างง่ายๆ จากชีวิตจริง: อะแดปเตอร์ USB สำหรับเต้ารับติดผนัง |
วิธีแม่แบบ |
รูปแบบการเขียนโปรแกรมเชิงพฤติกรรมที่ช่วยแก้ปัญหาการรวมและช่วยให้คุณเปลี่ยนขั้นตอนของอัลกอริทึมโดยไม่ต้องเปลี่ยนโครงสร้างของอัลกอริทึม ลองนึกภาพว่าเรามีอัลกอริทึมการประกอบรถยนต์ในรูปแบบของลำดับขั้นตอนการประกอบ: แชสซี -> ตัวถัง -> เครื่องยนต์ -> ภายในห้องโดยสาร หากเราใส่เฟรมเสริม เครื่องยนต์ที่ทรงพลังขึ้น หรือภายในห้องโดยสารที่มีไฟส่องสว่างเพิ่มเติม เราก็ไม่ต้องเปลี่ยนอัลกอริทึม และลำดับนามธรรมก็ยังคงเหมือนเดิม |
มัณฑนากร | รูปแบบนี้สร้าง wrapper สำหรับออบเจกต์เพื่อให้มีฟังก์ชันที่เป็นประโยชน์ เราจะถือว่าเป็นส่วนหนึ่งของบทความนี้ |
ใน Java.io คลาสต่อไปนี้ใช้รูปแบบ:
ลวดลาย | ใช้ใน java.io ที่ไหน |
---|---|
อแดปเตอร์ |
|
วิธีแม่แบบ | |
มัณฑนากร |
รูปแบบการตกแต่ง
ลองจินตนาการว่าเรากำลังอธิบายแบบจำลองสำหรับการออกแบบบ้าน
โดยทั่วไป วิธีการมีลักษณะดังนี้:
ในเบื้องต้นเรามีแบบบ้านให้เลือกหลายแบบ การกำหนดค่าขั้นต่ำคือหนึ่งชั้นพร้อมหลังคา จากนั้นเราใช้มัณฑนากรทุกประเภทเพื่อเปลี่ยนพารามิเตอร์เพิ่มเติมซึ่งส่งผลต่อราคาของบ้านโดยธรรมชาติ
เราสร้างคลาส House แบบนามธรรม:
public abstract class House {
String info;
public String getInfo() {
return info;
}
public abstract int getPrice();
}
ที่นี่เรามี 2 วิธี:
- getInfo()ส่งคืนข้อมูลเกี่ยวกับชื่อและคุณสมบัติของบ้านของเรา
- getPrice()ส่งกลับราคาของการกำหนดค่าบ้านปัจจุบัน
เรายังมีการติดตั้งแบบบ้านมาตรฐาน — อิฐและไม้:
public class BrickHouse extends House {
public BrickHouse() {
info = "Brick House";
}
@Override
public int getPrice() {
return 20_000;
}
}
public class WoodenHouse extends House {
public WoodenHouse() {
info = "Wooden House";
}
@Override
public int getPrice() {
return 25_000;
}
}
ทั้งสองคลาสสืบทอด คลาส Houseและแทนที่เมธอดราคา โดยกำหนดราคาเองสำหรับบ้านมาตรฐาน เราตั้งชื่อในตัวสร้าง
ต่อไปเราต้องเขียนคลาสมัณฑนากร คลาสเหล่านี้จะสืบทอดคลาสHouse ด้วย ในการทำเช่นนี้ เราสร้างคลาสมัณฑนากรนามธรรม
นั่นคือจุดที่เราจะใส่ตรรกะเพิ่มเติมสำหรับการเปลี่ยนแปลงวัตถุ ในขั้นต้นจะไม่มีตรรกะเพิ่มเติมและคลาสนามธรรมจะว่างเปล่า
abstract class HouseDecorator extends House {
}
ต่อไป เราสร้างการใช้งานมัณฑนากร เราจะสร้างหลายชั้นเรียนที่ให้เราเพิ่มคุณสมบัติเพิ่มเติมให้กับบ้าน:
public class SecondFloor extends HouseDecorator {
House house;
public SecondFloor(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 20_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + second floor";
}
}
ช่างต่อเติมบ้านชั้นสองของเรา |
คอนสตรัคเตอร์มัณฑนากรยอมรับบ้านที่เราจะ "ตกแต่ง" คือเพิ่มการดัดแปลง และเราลบล้างเมธอดgetPrice()และgetInfo()โดยส่งคืนข้อมูลเกี่ยวกับบ้านที่อัปเดตใหม่ตามบ้านเก่า
public class Garage extends HouseDecorator {
House house;
public Garage(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 5_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + garage";
}
}
ช่างต่อเติมโรงจอดรถบ้านเรา |
ตอนนี้เราสามารถปรับปรุงบ้านของเราด้วยมัณฑนากร ในการทำเช่นนี้เราต้องสร้างบ้าน:
House brickHouse = new BrickHouse();
ต่อไปเราตั้งค่าของเราบ้านตัวแปรเท่ากับมัณฑนากรคนใหม่ที่ผ่านในบ้านของเรา:
brickHouse = new SecondFloor(brickHouse);
ของเราบ้านตัวแปรคือบ้านที่มีชั้นสอง
ลองดูกรณีการใช้งานที่เกี่ยวข้องกับนักตกแต่ง:
ตัวอย่างโค้ด | เอาต์พุต |
---|---|
|
บ้านอิฐ 20,000 |
|
บ้านอิฐ+ชั้นสอง 40000 |
|
บ้านอิฐ+ชั้น2+โรงรถ 45000 |
|
บ้านไม้+โรงจอดรถ+ชั้น2 50000 |
|
บ้านไม้ 25000 บ้านไม้+โรงรถ 30000 |
ตัวอย่างนี้แสดงให้เห็นถึงประโยชน์ของการอัพเกรดวัตถุด้วยมัณฑนากร เราก็เลยไม่เปลี่ยนบ้านไม้วัตถุเอง แต่สร้างวัตถุใหม่ตามวัตถุเก่าแทน เราจะเห็นว่าข้อดีมาพร้อมกับข้อเสีย: เราสร้างวัตถุใหม่ในหน่วยความจำแต่ละครั้ง เพิ่มการใช้หน่วยความจำ
ดูแผนภาพ UML ของโปรแกรมของเรา:
มัณฑนากรมีการใช้งานที่เรียบง่ายสุด ๆ และเปลี่ยนแปลงอ็อบเจกต์แบบไดนามิก อัปเกรดพวกมัน มัณฑนากรสามารถรับรู้ได้โดยตัวสร้างของพวกเขาซึ่งใช้เป็นวัตถุพารามิเตอร์ของประเภทนามธรรมหรือส่วนต่อประสานเดียวกันกับคลาสปัจจุบัน ใน Java รูปแบบนี้ใช้กันอย่างแพร่หลายในคลาส I/O
ตัวอย่างเช่น ดังที่เราได้กล่าวไปแล้ว คลาสย่อยทั้งหมดของjava.io.InputStream , OutputStream , ReaderและWriterมีตัวสร้างที่ยอมรับออบเจกต์ของคลาสเดียวกัน
GO TO FULL VERSION