ณ จุดนี้ คุณคงเคยเจอรูปแบบการออกแบบแล้ว ตัวอย่างเช่นซิงเกิลตัน .

ลองนึกดูว่ารูปแบบคืออะไร เหตุใดจึงต้องใช้ และรูปแบบที่สร้างสรรค์คืออะไร (ตัวอย่างจากซิงเกิล) นอกจากนี้ เราจะศึกษารูปแบบใหม่: วิธีการจากโรงงาน

ในการพัฒนาซอฟต์แวร์รูปแบบการออกแบบคือโครงสร้างทางสถาปัตยกรรมที่ทำซ้ำได้ซึ่งแสดงถึงวิธีแก้ปัญหาการออกแบบภายในบริบทที่เกิดซ้ำ

โดยทั่วไปแล้ว รูปแบบไม่ใช่โซลูชันขั้นสุดท้ายที่สามารถแปลงเป็นรหัสได้โดยตรง เป็นเพียงแบบจำลองการแก้ปัญหาที่สามารถนำไปใช้ในสถานการณ์ต่างๆ

รูปแบบการสร้างสรรค์คือรูปแบบการออกแบบที่เกี่ยวข้องกับกระบวนการสร้างวัตถุ ทำให้สามารถสร้างระบบที่เป็นอิสระจากวิธีที่ใช้ในการสร้าง เรียบเรียง และนำเสนอวัตถุ

เมธอดโรงงานเป็นรูปแบบการออกแบบเชิงสร้างสรรค์ที่กำหนดอินเทอร์เฟซทั่วไปสำหรับการสร้างออบเจกต์ในคลาสพาเรนต์ ทำให้สามารถสร้างออบเจกต์เหล่านี้ในระดับลูกหลานได้ ในขณะที่สร้าง ลูกหลานสามารถกำหนดได้ว่าจะสร้างคลาสใด

รูปแบบแก้ปัญหาอะไร

ลองนึกภาพว่าคุณตัดสินใจที่จะสร้างโปรแกรมการจัดส่ง เริ่มแรก คุณจะจ้างคนส่งของพร้อมรถและใช้กรถคัดค้านการเป็นตัวแทนของรถจัดส่งในโปรแกรม บริการจัดส่งพัสดุจากจุด A ไปยังจุด B เป็นต้น ง่ายนิดเดียว.

โปรแกรมกำลังได้รับความนิยม ธุรกิจของคุณกำลังเติบโตและคุณต้องการขยายไปสู่ตลาดใหม่ๆ ตัวอย่างเช่น คุณสามารถเริ่มส่งอาหารและขนส่งด้วย ในกรณีนี้ สามารถส่งอาหารโดยบริการจัดส่งด้วยการเดินเท้า สกู๊ตเตอร์ และจักรยาน แต่รถบรรทุกจำเป็นสำหรับการขนส่งสินค้า

ตอนนี้คุณต้องติดตามหลายสิ่งหลายอย่าง (เมื่อใด ให้ใคร อะไร และราคาเท่าไร) รวมถึงจำนวนที่ขนส่งแต่ละรายการสามารถบรรทุกได้ โหมดการขนส่งใหม่มีความเร็วและความจุที่แตกต่างกัน จากนั้นคุณสังเกตเห็นว่าเอนทิตีส่วนใหญ่ในโปรแกรมของคุณเชื่อมโยงอย่างมากกับรถระดับ. คุณทราบดีว่าเพื่อให้โปรแกรมของคุณทำงานร่วมกับวิธีการจัดส่งอื่นๆ ได้ คุณจะต้องเขียนโค้ดฐานที่มีอยู่ใหม่และทำใหม่ทุกครั้งที่คุณเพิ่มยานพาหนะใหม่

ผลลัพธ์ที่ได้คือโค้ดที่น่ากลัวซึ่งเต็มไปด้วยข้อความแสดงเงื่อนไขที่ดำเนินการต่างๆ กันขึ้นอยู่กับประเภทของการขนส่ง

การแก้ไขปัญหา

รูปแบบเมธอดโรงงานแนะนำให้สร้างอ็อบเจกต์โดยการเรียกเมธอดพิเศษจากโรงงานแทนที่จะใช้โอเปอเรเตอร์ใหม่ โดยตรง คลาสย่อยของคลาสที่มีเมธอดโรงงานสามารถแก้ไขวัตถุที่สร้างขึ้นของยานพาหนะเฉพาะได้ เมื่อมองแวบแรก สิ่งนี้อาจดูไม่มีจุดหมาย: เราเพิ่งย้ายการเรียกตัวสร้างจากที่หนึ่งในโปรแกรมไปยังอีกที่หนึ่ง แต่ตอนนี้คุณสามารถแทนที่เมธอดโรงงานในคลาสย่อยเพื่อเปลี่ยนประเภทการขนส่งที่กำลังสร้างได้

ลองดูแผนภาพชั้นเรียนสำหรับแนวทางนี้:

เพื่อให้ระบบนี้ทำงานได้ อ็อบเจ็กต์ที่ส่งคืนทั้งหมดต้องมีอินเทอร์เฟซร่วมกัน คลาสย่อยจะสามารถสร้างวัตถุของคลาสต่างๆ ที่ใช้อินเทอร์เฟซนี้

ตัวอย่างเช่น คลาส TruckและCarใช้ อินเทอร์เฟซ CourierTransportด้วยวิธีการส่งมอบ แต่ละประเภทเหล่านี้ใช้วิธีที่แตกต่างกัน: รถบรรทุกส่งสินค้า ในขณะที่รถยนต์ส่งอาหาร บรรจุภัณฑ์ และอื่นๆ เมธอดโรงงานใน คลาส TruckCreatorส่งคืนวัตถุรถบรรทุก และ คลาส CarCreatorส่งคืนวัตถุรถยนต์

สำหรับไคลเอ็นต์ของวิธีการโรงงาน ไม่มีความแตกต่างระหว่างวัตถุเหล่านี้ เนื่องจากมันจะถือว่าวัตถุเหล่านี้เป็นCourierTransport ที่ เป็นนามธรรม ลูกค้าจะสนใจอย่างลึกซึ้งว่าวัตถุมีวิธีการส่งมอบ แต่วิธีการทำงานนั้นไม่สำคัญ

การใช้งานใน Java:


public interface CourierTransport {
	void deliver();
}
public class Car implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The package is being delivered by car");
	}
}
public class Truck implements CourierTransport {
	@Override
	public void deliver() {
    		System.out.println("The freight is being delivered by truck");
	}
}
public abstract class CourierTransportCreator {
	public abstract CourierTransport createTransport();
}
public class CarCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Car();
	}
}
public class TruckCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Truck();
	}
}
 
public class Delivery {
	private String address;
	private CourierTransport courierTransport;
 
	public void Delivery() {
	}
 
	public Delivery(String address, CourierTransport courierTransport) {
    	this.address = address;
    	this.courierTransport = courierTransport;
	}
 
	public CourierTransport getCourierTransport() {
    		return courierTransport;
	}
 
	public void setCourierTransport(CourierTransport courierTransport) {
    		this.courierTransport = courierTransport;
	}
 
	public String getAddress() {
    		return address;
	}
 
	public void setAddress(String address) {
    		this.address = address;
	}
}
public static void main(String[] args) {
    	// Accept a new type of order from the database (pseudocode)
    	String type = database.getTypeOfDeliver();
 
    	Delivery delivery = new Delivery();
    	
    	// Set the transport for delivery
        delivery.setCourierTransport(getCourierTransportByType(type));
    	
    	// Make the delivery
        delivery.getCourierTransport().deliver();
 
	}
 
	public static CourierTransport getCourierTransportByType(String type) {
    	switch (type) {
        	case "CarDelivery":
            	return new CarCreator().createTransport();
        	case "TruckDelivery":
            	return new TruckCreator().createTransport();
        	default:
            	throw new RuntimeException();
	    }
	}
    

หากเราต้องการสร้างวัตถุนำส่งใหม่ โปรแกรมจะสร้างวัตถุขนส่งที่เหมาะสมให้โดยอัตโนมัติ

เราควรใช้รูปแบบนี้เมื่อใด

1. เมื่อคุณไม่ทราบล่วงหน้าถึงประเภทและการพึ่งพาของออบเจกต์ที่โค้ดของคุณจำเป็นต้องทำงานด้วย

วิธีการของโรงงานจะแยกรหัสสำหรับรูปแบบการขนส่งการผลิตออกจากรหัสที่ใช้การขนส่ง ด้วยเหตุนี้ โค้ดสำหรับสร้างออบเจกต์จึงขยายได้โดยไม่ต้องแตะโค้ดที่เหลือ

ตัวอย่างเช่น หากต้องการเพิ่มการรองรับสำหรับการขนส่งประเภทใหม่ คุณต้องสร้างคลาสย่อยใหม่และกำหนดวิธีการจากโรงงานซึ่งจะส่งคืนอินสแตนซ์ของการขนส่งใหม่

2. เมื่อคุณต้องการประหยัดทรัพยากรระบบโดยการนำวัตถุที่มีอยู่กลับมาใช้ใหม่แทนการสร้างวัตถุใหม่

ปัญหานี้มักเกิดขึ้นเมื่อทำงานกับวัตถุที่ใช้ทรัพยากรมาก เช่น การเชื่อมต่อฐานข้อมูล ระบบไฟล์ เป็นต้น

นึกถึงขั้นตอนที่คุณต้องทำเพื่อนำวัตถุที่มีอยู่กลับมาใช้ใหม่:

  1. ขั้นแรก คุณต้องสร้างพื้นที่เก็บข้อมูลที่ใช้ร่วมกันเพื่อจัดเก็บวัตถุทั้งหมดที่คุณสร้างขึ้น

  2. เมื่อขอวัตถุใหม่ คุณต้องดูในที่เก็บและตรวจสอบว่ามีวัตถุที่มีอยู่หรือไม่

  3. ส่งคืนวัตถุไปยังรหัสลูกค้า

  4. แต่ถ้าไม่มีอ็อบเจ็กต์ให้สร้างใหม่และเพิ่มไปยังที่เก็บ

ต้องใส่โค้ดทั้งหมดนี้ไว้ที่ใดที่หนึ่งซึ่งจะไม่เกะกะโค้ดไคลเอนต์ สถานที่ที่สะดวกที่สุดคือตัวสร้างเนื่องจากเราต้องการเพียงการตรวจสอบเหล่านี้ทั้งหมดเมื่อสร้างวัตถุ อนิจจา ตัวสร้างจะสร้างวัตถุใหม่เสมอ — มันไม่สามารถส่งคืนวัตถุที่มีอยู่ได้

นั่นหมายความว่าจำเป็นต้องมีวิธีอื่นที่สามารถส่งคืนทั้งวัตถุที่มีอยู่และวัตถุใหม่ นี่จะเป็นวิธีการของโรงงาน

3. เมื่อคุณต้องการอนุญาตให้ผู้ใช้ขยายส่วนต่างๆ ของเฟรมเวิร์กหรือไลบรารีของคุณ

ผู้ใช้สามารถขยายคลาสเฟรมเวิร์กของคุณผ่านการสืบทอด แต่คุณจะทำให้เฟรมเวิร์กสร้างวัตถุของคลาสใหม่เหล่านี้แทนที่จะเป็นคลาสมาตรฐานได้อย่างไร

วิธีแก้ไขคือให้ผู้ใช้ขยายไม่เพียงแค่คอมโพเนนต์เท่านั้น แต่ยังรวมถึงคลาสที่สร้างคอมโพเนนต์เหล่านั้นด้วย และสำหรับสิ่งนี้ การสร้างคลาสจะต้องมีวิธีการสร้างเฉพาะที่สามารถกำหนดได้

ข้อดี

  • แยกคลาสออกจากคลาสการขนส่งเฉพาะ
  • เก็บรหัสสำหรับสร้างรูปแบบการขนส่งไว้ในที่เดียว ทำให้รักษารหัสได้ง่ายขึ้น
  • ลดความซับซ้อนของการเพิ่มโหมดการขนส่งใหม่ๆ ลงในโปรแกรม
  • ใช้หลักการเปิด-ปิด

ข้อเสีย

อาจนำไปสู่ลำดับชั้นของคลาสคู่ขนานขนาดใหญ่ เนื่องจากแต่ละคลาสผลิตภัณฑ์ต้องมีคลาสย่อยของผู้สร้างของตัวเอง

มาสรุปกัน

คุณได้เรียนรู้เกี่ยวกับรูปแบบวิธีการของโรงงานและได้เห็นการใช้งานที่เป็นไปได้อย่างหนึ่ง รูปแบบนี้มักใช้ในไลบรารีต่างๆ ที่มีวัตถุสำหรับสร้างวัตถุอื่นๆ

ใช้รูปแบบเมธอดโรงงานเมื่อคุณต้องการเพิ่มอ็อบเจกต์ใหม่ของคลาสย่อยของคลาสที่มีอยู่เพื่อให้โต้ตอบกับตรรกะทางธุรกิจหลักของคุณ และไม่ทำให้โค้ดของคุณขยายใหญ่ขึ้นเนื่องจากบริบทที่แตกต่างกัน