आप इस मामले में Visitor design pattern का उपयोग कर सकते हैं। आपके Product
वर्ग में addToBill
विधि लागू करें और तर्क के रूप में एक उदाहरण पास करें जो आपके बिल इंटरफ़ेस को लागू करता है, IBill
। IBill
एक विधि addToTotal
का समर्थन करता है जो आइटम में उपलब्ध सभी आवश्यक जानकारी स्वीकार करेगा; आपके मामले में, यह एक कीमत है। उदाहरण के लिए:
interface IBill {
/* needs to be public because PHP doesn't understand the concept of
friendship
*/
function addToTotal($price);
}
class Bill implements IBill {
private $total = 0;
function addToTotal($price) {
$this->total += $price;
}
...
}
class ShoppingCart {
private $items = array();
function addItem($id, $product, $quantity) {
if (isset($this->items[$id])) {
$this->items[$id]->addQuantity($quantity);
} else {
$this->items[$id] = new LineItem($product, $quantity);
}
}
private createBill() {
$bill = new Bill;
foreach ($this->items AS $lineItem) {
$lineItem->addToBill($bill);
}
return ...;
}
}
class LineItem {
private $product, $quantity;
function __constructor($product, $quantity) {...}
function addToBill(IBill $bill) {
$this->product->addToBill($bill, $quantity);
}
function addQuantity($quantity) {
$this->quantity += $quantity;
}
...
}
class Product {
private $name, $description, $price;
function __constructor(...) {...}
function addToBill(IBill $bill, $quantity) {
$bill->addToTotal($this->price * $quantity);
}
...
}
हालांकि, आप हमेशा कमजोर जमीन पर उड़ जाएंगे। उपरोक्त को addToTotal
जैसी विधि की आवश्यकता होती है, जो एक आविष्कार (कुल पंक्ति वस्तु मूल्यों और मात्राओं के उत्पादों के योग से मेल खाना चाहिए) का परिचय देता है, केवल "बताओ, मत पूछो" से बचने के लिए कहा जाता है। आप बिना addToTotal
: * Bill
के साथ इसे करने का प्रयास कर सकते हैं; ShoppingCart
कुल का ट्रैक रखता है। उत्पाद & मात्रा के अतिरिक्त मूल्य को addItem
पर पास करें; addItem
कुल अद्यतन। यह कक्षाओं के उद्देश्य को कुछ हद तक हरा देता है, क्योंकि आप LineItem
या Product
का उपयोग नहीं कर रहे हैं।यह एक आविष्कार भी जोड़ता है कि उत्तीर्ण मूल्य और उत्पाद बनाया गया था जब मूल्य बनाया जाना चाहिए, हालांकि यदि वे नहीं करते हैं, तो यह मुद्दों का कारण नहीं बनना चाहिए (यह केवल अजीब होगा)। * addItem
Product
और LineItem
को तत्काल करें; addItem
कुल अद्यतन। पहले जोड़े गए अतिरिक्त आइटम जोड़ते समय, या तो एक अतिरिक्त आविष्कार होना चाहिए कि पास-इन $price
को पिछली कॉल में पारित राशि से मेल खाना चाहिए, या addItem
को अतिरिक्त, मौजूदा आइटम जोड़ने की अनुमति नहीं दी जा सकती है। * सभी वस्तुओं को एक साथ दूर करें। ShoppingCart
उत्पाद आईडी और मात्रा को स्टोर करता है। addItem
पर प्रत्येक कॉल कुल अपडेट करता है। createBill
पहले से गणना की गई कुल का उपयोग करता है। दूसरों की तुलना में भी अधिक, यह separate concerns को एकजुट करता है।
अन्य संभावित डिज़ाइन हैं, लेकिन हर किसी को किसी प्रकार की समस्या से पीड़ित है, आमतौर पर चिंताओं को अलग करने, आविष्कारों को पेश करने और जटिलता जोड़ने से संबंधित है। कुल मिलाकर, एक पंक्ति वस्तु की कुल कीमत को सीधे उस विधि के भीतर एक्सेस करना जो कुल गणना करता है न केवल सबसे सरल, लेकिन सबसे साफ और कम से कम त्रुटियों का उत्पादन करने की संभावना है।
यदि एक शॉपिंग कार्ट में सामानों की सूची है, तो शॉपिंग कार्ट प्रत्येक आइटम की कीमत के मूल्य को जानने में सक्षम क्यों है? – user12345613
"बताओ मत पूछो" के बाद - शिष्य यह बुरा लगता है। – Tom
आपने यह कहां सुना "सिद्धांत मत पूछो" सिद्धांत? मैंने इसके हारे में नहीं सुना है। – xxpor