मैंने पहले इस प्रश्न का एक संस्करण पूछने की कोशिश की है। मुझे कुछ सहायक उत्तर मिल गए, लेकिन अभी भी कुछ भी नहीं जो मुझे काफी सही लगा। ऐसा लगता है कि यह वास्तव में क्रैक करने के लिए मुश्किल नहीं होना चाहिए, लेकिन मैं एक सुरुचिपूर्ण सरल समाधान खोजने में सक्षम नहीं हूं। (यहाँ मेरी पिछली पोस्ट है, लेकिन इतनी के रूप में पहले स्पष्टीकरण जो बहुत जटिल समाधान को बढ़ावा मिल रहा से प्रभावित होने की नहीं पहले प्रक्रियात्मक कोड के रूप में यहां कहा गया है समस्या को देखने के लिए प्रयास करें: Design pattern for cost calculator app?)पॉलिमॉर्फिज्म रिफैक्टरिंग या इसी तरह के सशर्त को बदलें?
मूल रूप से, समस्या यह है परियोजनाओं के लिए आवश्यक घंटों के लिए एक कैलकुलेटर बनाने के लिए जिसमें कई सेवाएं हो सकती हैं। इस मामले में "लेखन" और "विश्लेषण"। घंटों की गणना विभिन्न सेवाओं के लिए अलग-अलग की जाती है: लेखन की गणना उत्पादों की संख्या के साथ "प्रति उत्पाद" घंटे की दर गुणा करके की जाती है, और परियोजना में अधिक उत्पाद शामिल होते हैं, घंटे की दर कम होती है, लेकिन कुल संख्या घंटों को क्रमशः संचित किया जाता है (यानी एक मध्यम आकार की परियोजना के लिए आप छोटी रेंज मूल्य निर्धारण दोनों लेते हैं और फिर वास्तविक उत्पादों की संख्या तक मध्यम श्रेणी मूल्य निर्धारण जोड़ते हैं)। जबकि विश्लेषण के लिए यह बहुत आसान है, यह प्रत्येक आकार सीमा के लिए सिर्फ एक थोक दर है।
आप इसे एक सुरुचिपूर्ण और अधिमानतः सरल ऑब्जेक्ट उन्मुख संस्करण में कैसे प्रतिक्रिया दे पाएंगे (कृपया ध्यान दें कि मैं इसे पूरी तरह से प्रक्रियात्मक तरीके से कभी नहीं लिखूंगा, यह केवल किसी अन्य तरीके से समस्या को दिखाने के लिए है)।
मैं फैक्ट्री, रणनीति और सजावटी पैटर्न के मामले में सोच रहा हूं, लेकिन कोई भी अच्छी तरह से काम नहीं कर सकता। (मैंने कुछ समय पहले हेड फर्स्ट डिज़ाइन पैटर्न पढ़ा था, और वर्णित सजावटी और फैक्ट्री पैटर्न दोनों में इस समस्या के कुछ समानताएं हैं, लेकिन मुझे वहां बताए गए अच्छे समाधान के रूप में उन्हें देखने में परेशानी है। सजावटी उदाहरण केवल मसालों को जोड़ने के लिए बहुत जटिल लग रहा था , लेकिन शायद यह बेहतर काम कर सकता है, मुझे नहीं पता। कम से कम तथ्य यह है कि घंटों की गणना ने प्रगतिशील रूप से मुझे सजावटी पैटर्न के बारे में सोचा ... और पिज्जा कारखाने के साथ पुस्तक से फैक्ट्री पैटर्न उदाहरण .. .वैसे ही यह कक्षाओं के इस तरह के हास्यास्पद विस्फोट को कम से कम उनके उदाहरण में प्रतीत होता है। मुझे कारखाने के पैटर्न के लिए अच्छा उपयोग मिला है, लेकिन मैं नहीं देख सकता कि मैं कक्षाओं का वास्तव में जटिल सेट प्राप्त किए बिना इसका उपयोग कैसे कर सकता हूं)
मुख्य लक्ष्य केवल एक स्थान (ढीला युग्मन आदि) में बदलना होगा यदि मैं एक नया paramete जोड़ना चाहता था आर (एक और आकार, जैसे XSMALL, और/या एक अन्य सेवा, जैसे "प्रशासन") कहें। यहां प्रक्रियात्मक कोड उदाहरण है:
public class Conditional
{
private int _numberOfManuals;
private string _serviceType;
private const int SMALL = 2;
private const int MEDIUM = 8;
public int GetHours()
{
if (_numberOfManuals <= SMALL)
{
if (_serviceType == "writing")
return 30 * _numberOfManuals;
if (_serviceType == "analysis")
return 10;
}
else if (_numberOfManuals <= MEDIUM)
{
if (_serviceType == "writing")
return (SMALL * 30) + (20 * _numberOfManuals - SMALL);
if (_serviceType == "analysis")
return 20;
}
else //i.e. LARGE
{
if (_serviceType == "writing")
return (SMALL * 30) + (20 * (MEDIUM - SMALL)) + (10 * _numberOfManuals - MEDIUM);
if (_serviceType == "analysis")
return 30;
}
return 0; //Just a default fallback for this contrived example
}
}
सभी उत्तरों की सराहना की जाती है! (लेकिन जैसा कि मैंने अपनी पिछली पोस्ट में कहा था, मैं केवल "इस पैटर्न को आजमाएं" की बजाय वास्तविक कोड उदाहरणों की सराहना करता हूं, क्योंकि जैसा कि मैंने उल्लेख किया है, वही है जो मुझे परेशानी हो रही है ...) मुझे उम्मीद है कि किसी के पास वास्तव में एक शानदार समाधान है इस समस्या यह है कि मैं वास्तव में शुरू से ही सोचा था कि वास्तव में आसान होगा ... के
============================= ===========================
नए सदस्य:
मैं अब तक सभी प्रश्नों के उत्तर की सराहना करते हैं, लेकिन मैं कर रहा हूँ अभी भी समस्या के लिए वास्तव में सरल और लचीला समाधान नहीं देख रहा है (एक मैंने सोचा था कि पहले बहुत जटिल नहीं होगा, लेकिन जाहिर है)। यह भी हो सकता है कि मैंने अभी तक प्रत्येक उत्तर को सही ढंग से समझा नहीं है। लेकिन मैंने सोचा कि मैं इसे काम करने के लिए अपने वर्तमान प्रयास को पोस्ट करूंगा (कुछ जवाबों के साथ यहां जवाबों में सभी अलग-अलग कोण पढ़ने से)। कृपया मुझे बताएं कि क्या मैं सही रास्ते पर हूं या नहीं। लेकिन कम से कम अब ऐसा लगता है कि यह अधिक लचीला होना शुरू हो रहा है ... मैं बहुत से स्थानों में बदलने के बिना आसानी से नए पैरामीटर जोड़ सकता हूं (मुझे लगता है!), और सशर्त तर्क एक ही स्थान पर है। मेरे पास मूल डेटा प्राप्त करने के लिए xml में कुछ है, जो समस्या का हिस्सा सरल बनाता है, और इसका एक हिस्सा एक रणनीति प्रकार समाधान का प्रयास है।
कोड यह रहा:
public class Service
{
protected HourCalculatingStrategy _calculatingStrategy;
public int NumberOfProducts { get; set; }
public const int SMALL = 3;
public const int MEDIUM = 9;
public const int LARGE = 20;
protected string _serviceType;
protected Dictionary<string, decimal> _reuseLevels;
protected Service(int numberOfProducts)
{
NumberOfProducts = numberOfProducts;
}
public virtual decimal GetHours()
{
decimal hours = _calculatingStrategy.GetHours(NumberOfProducts, _serviceType);
return hours;
}
}
public class WritingService : Service
{
public WritingService(int numberOfProducts)
: base(numberOfProducts)
{
_calculatingStrategy = new VariableCalculatingStrategy();
_serviceType = "writing";
}
}
class AnalysisService : Service
{
public AnalysisService(int numberOfProducts)
: base(numberOfProducts)
{
_calculatingStrategy = new FixedCalculatingStrategy();
_serviceType = "analysis";
}
}
public abstract class HourCalculatingStrategy
{
public abstract int GetHours(int numberOfProducts, string serviceType);
protected int GetHourRate(string serviceType, Size size)
{
XmlDocument doc = new XmlDocument();
doc.Load("calculatorData.xml");
string result = doc.SelectSingleNode(string.Format("//*[@type='{0}']/{1}", serviceType, size)).InnerText;
return int.Parse(result);
}
protected Size GetSize(int index)
{
if (index < Service.SMALL)
return Size.small;
if (index < Service.MEDIUM)
return Size.medium;
if (index < Service.LARGE)
return Size.large;
return Size.xlarge;
}
}
public class VariableCalculatingStrategy : HourCalculatingStrategy
{
public override int GetHours(int numberOfProducts, string serviceType)
{
int hours = 0;
for (int i = 0; i < numberOfProducts; i++)
{
hours += GetHourRate(serviceType, GetSize(i + 1));
}
return hours;
}
}
public class FixedCalculatingStrategy : HourCalculatingStrategy
{
public override int GetHours(int numberOfProducts, string serviceType)
{
return GetHourRate(serviceType, GetSize(numberOfProducts));
}
}
और एक साधारण उदाहरण के रूप में है कि यह कॉल (मुझे लगता है कि मैं भी सेवा वस्तुओं से युक्त एक शब्दकोश के साथ एक आवरण परियोजना वर्ग हो सकता था, लेकिन मुझे लगता है कि करने के लिए नहीं मिला है):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
List<int> quantities = new List<int>();
for (int i = 0; i < 100; i++)
{
quantities.Add(i);
}
comboBoxNumberOfProducts.DataSource = quantities;
}
private void CreateProject()
{
int numberOfProducts = (int)comboBoxNumberOfProducts.SelectedItem;
Service writing = new WritingService(numberOfProducts);
Service analysis = new AnalysisService(numberOfProducts);
labelWriterHours.Text = writing.GetHours().ToString();
labelAnalysisHours.Text = analysis.GetHours().ToString();
}
private void comboBoxNumberOfProducts_SelectedIndexChanged(object sender, EventArgs e)
{
CreateProject();
}
}
(मैं एक्सएमएल शामिल करने में सक्षम है क्योंकि यह स्वचालित रूप से इस पृष्ठ पर स्वरूपित गया नहीं था, लेकिन यह मूल रूप से बस प्रत्येक सेवा प्रकार के साथ तत्वों का एक समूह है, और प्रत्येक सेवा के साथ आकार युक्त प्रकार है मूल्यों के रूप में घंटे की दर।)
मुझे यकीन नहीं है कि क्या मैं समस्या को xml फ़ाइल पर दबा रहा हूं (मुझे अभी भी प्रत्येक नए servicetype के लिए नए तत्व जोड़ना होगा, और प्रत्येक servicetype में किसी भी नए आकार के लिए तत्व जोड़ें यदि वह बदल गया ।) लेकिन शायद यह हासिल करना असंभव है कि मैं क्या करने की कोशिश कर रहा हूं और कम से कम उस प्रकार के परिवर्तन को नहीं करना है। एक डेटाबेस का उपयोग करना नहीं बल्कि एक्सएमएल से परिवर्तन एक क्षेत्र और एक पंक्ति जोड़ने के रूप में सरल होगा:
ServiceType छोटे मध्यम बड़े
लेखन विश्लेषण 56 104 200
(सीधे शब्दों में यहां "टेबल" के रूप में स्वरूपित है, हालांकि कॉलम काफी गठबंधन नहीं हैं ... हालांकि मैं डेटाबेस डिज़ाइन पर सबसे अच्छा नहीं हूं, और शायद इसे अलग-अलग किया जाना चाहिए, लेकिन आपको विचार मिल रहा है ...)
कृपया मुझे बताएं कि आप क्या सोचते हैं!
यह एक छोटे से परिवर्तन है, और वास्तव में अपने व्यापक पैटर्न सवाल के किसी भी उत्तर नहीं मिलता है, लेकिन आप, "लेखन" मामले में, रिकर्सिवली समारोह आह्वान सकता: 'वापसी GetHours (SMALL) + 20 * _numberOfManuals - लघु); 'जब आप XSMALL जोड़ना चाहते हैं, तो यह आपकी सहायता करता है, और तर्कसंगत रूप से अधिक स्पष्ट रूप से पढ़ता है। –
+1 मुझे यह पसंद है जब लोग स्वच्छ कोड लिखने के बारे में भावुक हैं –