एक वर्ग की जटिलता को कम करना


10

मैंने कुछ उत्तरों को देखा है और Google पर खोजा है, लेकिन मुझे कुछ भी मददगार नहीं मिला (यानी, इसका कोई दुष्प्रभाव नहीं होगा)।

अमूर्त में मेरी समस्या यह है कि मेरे पास एक वस्तु है और उस पर परिचालन का एक लंबा अनुक्रम करने की आवश्यकता है; मैं इसे असेंबली लाइन की तरह समझता हूं, जैसे कार बनाना।

मेरा मानना ​​है कि इन ऑब्जेक्ट्स को मेथड ऑब्जेक्ट्स कहा जाएगा ।

तो इस उदाहरण में कुछ बिंदु पर मेरे पास एक CarWithoutUpholstery होगी, जिस पर मुझे फिर installBackSeat, installFrontSeat, installWoodenInserts चलाने की आवश्यकता होगी (संचालन एक दूसरे के साथ हस्तक्षेप नहीं करते हैं, और समानांतर में भी किया जा सकता है)। ये संचालन CarWithoutUpholstery.worker () द्वारा किया जाता है और एक नई वस्तु प्राप्त करता है जो CarWithUpholstery होगी, जिस पर मैं तब CleanInsides (), VerNoUpholsteryDefects (), और इसी तरह चलाऊंगा।

एक ही चरण में परिचालन पहले से ही स्वतंत्र है, यानी, मैं पहले से ही उनमें से एक सबसेट के साथ जूझ रहा हूं जिसे किसी भी क्रम में निष्पादित किया जा सकता है (आगे और पीछे की सीटें किसी भी क्रम में स्थापित की जा सकती हैं)।

मेरा तर्क वर्तमान में कार्यान्वयन की सादगी के लिए प्रतिबिंब का उपयोग करता है।

यही है, एक बार जब मेरे पास CarWithoutUpholstery है, तो ऑब्जेक्ट खुद को PerformSomething () नामक विधियों के लिए निरीक्षण करता है। उस समय यह इन सभी विधियों को कार्यान्वित करता है:

myObject.perform001SomeOperation();
myObject.perform002SomeOtherOperation();
...

त्रुटियों और सामान की जाँच करते समय। जबकि ऑपरेशन का आदेश महत्वहीन है, मैंने कभी-कभी एक लेक्सोग्राफ़िक ऑर्डर सौंपा है, जिसमें मुझे पता चलता है कि कुछ ऑर्डर सभी के बाद महत्वपूर्ण है। यह YAGNI का विरोधाभास करता है , लेकिन इसकी लागत बहुत कम थी - एक साधारण प्रकार () - और यह एक बड़े पैमाने पर विधि का नाम बदलने (या परीक्षण करने के कुछ अन्य तरीके पेश कर सकता है, जैसे कि तरीकों की एक सरणी) रेखा के नीचे।

एक अलग उदाहरण

हम कहते हैं कि मुझे एक कार बनाने के बजाय किसी पर एक गुप्त पुलिस रिपोर्ट संकलित करनी होगी, और इसे मेरे ईविल ओवरलॉर्ड को जमा करना होगा । मेरी अंतिम वस्तु एक रेडीपोर्ट होगी। इसके निर्माण के लिए मैं बुनियादी जानकारी (नाम, उपनाम, पति या पत्नी) इकट्ठा करके शुरू करता हूं। यह मेरा चरण ए है। इस बात पर निर्भर करता है कि पति या पत्नी है या नहीं, मुझे इसके बाद बी 1 या बी 2 के चरणों में जाना होगा, और एक या दो लोगों पर कामुकता संबंधी डेटा एकत्र करना होगा। यह नाइट लाइफ, स्ट्रीट कैम, सेक्स शॉप की बिक्री प्राप्तियों और क्या नहीं, को नियंत्रित करने वाले विभिन्न ईविल मिनियंस के लिए कई अलग-अलग प्रश्नों से बना है। इत्यादि इत्यादि।

यदि पीड़ित का कोई परिवार नहीं है, तो मैं GetInformationAboutFamily चरण में भी प्रवेश नहीं करूंगा, लेकिन अगर मैं करता हूं, तो यह अप्रासंगिक है कि क्या मैं पहले पिता या माता या भाई-बहन (यदि कोई हो) को लक्षित करता हूं। लेकिन मैं ऐसा नहीं कर सकता, अगर मैंने फैमिलीस्टैटसकैच नहीं किया है, जो कि पहले के चरण से संबंधित है।

यह सब अद्भुत काम करता है ...

  • अगर मुझे कुछ अतिरिक्त ऑपरेशन की आवश्यकता है, तो मुझे केवल एक निजी विधि जोड़ने की आवश्यकता है,
  • यदि ऑपरेशन कई चरणों में सामान्य है, तो मुझे यह एक सुपरक्लास से विरासत में मिल सकता है,
  • संचालन सरल और आत्म-निहित हैं। एक ऑपरेशन के बाद कभी भी कोई मान दूसरों (कार्य है कि में से किसी के लिए आवश्यक है है , एक अलग चरण में प्रदर्शन कर रहे हैं)
  • रेखा से नीचे की वस्तुओं को कई परीक्षण करने की आवश्यकता नहीं है क्योंकि वे तब भी मौजूद नहीं हो सकते थे जब उनके निर्माता वस्तुओं ने उन स्थितियों को पहले स्थान पर सत्यापित नहीं किया था। यानी, जब डैशबोर्ड में आवेषण रखते हैं, डैशबोर्ड की सफाई करते हैं और डैशबोर्ड की पुष्टि करते हैं, तो मुझे यह सत्यापित करने की आवश्यकता नहीं है कि डैशबोर्ड वास्तव में है
  • यह आसान परीक्षण के लिए अनुमति देता है। मैं आसानी से एक आंशिक वस्तु का मजाक उड़ा सकता हूं और उस पर कोई भी विधि चला सकता हूं, और सभी ऑपरेशन नियतात्मक ब्लैक बॉक्स हैं।

...परंतु...

समस्या तब पैदा हुई जब मैंने अपनी एक विधि ऑब्जेक्ट में एक आखिरी ऑपरेशन जोड़ा , जिससे समग्र मॉड्यूल एक अनिवार्य जटिलता सूचकांक ("एन प्राइवेट तरीकों से कम") से अधिक हो गया।

मैंने पहले ही मामले को ऊपर ले लिया है और सुझाव दिया है कि इस मामले में, निजी तरीकों का धन आपदा का कोई विवरण नहीं है। जटिलता है वहाँ है, लेकिन यह वहाँ है, क्योंकि आपरेशन है जटिल है, और वास्तव में यह सब है कि जटिल नहीं है - यह सिर्फ है लंबे समय तक

ईविल ओवरलॉर्ड उदाहरण का उपयोग करते हुए, मेरी समस्या यह है कि ईविल ओवरलॉर्ड (उर्फ वह कौन होगा, जिसने इनकार नहीं किया) ने सभी आहार संबंधी जानकारी का अनुरोध किया , मेरे आहार मंत्रालय ने मुझे बताया कि मुझे रेस्तरां, किचनसेट, स्ट्रीट वेंडर, बिना लाइसेंस वाले स्ट्रीट वेंडर्स, ग्रीनहाउस को क्वेरी करने की आवश्यकता है। मालिकों आदि, और ईविल (उप) अधिपति - जिसे वे कौन कौन हैं, यह भी ज्ञात नहीं है - शिकायत है कि मैं GetDietaryInformation चरण में बहुत सारे प्रश्नों का प्रदर्शन कर रहा हूं।

नोट : मुझे पता है कि कई बिंदुओं से यह बिल्कुल भी समस्या नहीं है (संभावित प्रदर्शन मुद्दों की अनदेखी)। यह सब हो रहा है कि एक विशिष्ट मीट्रिक दुखी है, और उसके लिए औचित्य है।

मुझे लगता है कि मैं क्या कर सकता था

पहले के अलावा, ये सभी विकल्प उल्लेखनीय हैं और, मुझे लगता है, रक्षात्मक।

  • मैंने सत्यापित किया है कि मैं डरपोक हो सकता हूं और अपने आधे तरीकों की घोषणा कर सकता हूं protected। लेकिन मैं परीक्षण प्रक्रिया में एक कमजोरी का शोषण कर रहा हूं, और पकड़े जाने पर खुद को सही ठहराने के अलावा, मुझे यह पसंद नहीं है। इसके अलावा, यह एक स्टॉपगैप उपाय है। क्या होगा यदि आवश्यक संचालन की संख्या दोगुनी हो जाए? बेखबर, लेकिन फिर क्या?
  • मैं मनमाने ढंग से इस चरण को AnnealedObjectAlpha, AnnealedObjectBravo और AnnealedObjectCharlie में विभाजित कर सकता हूं, और प्रत्येक चरण में एक तिहाई ऑपरेशन किए जा रहे हैं। मैं इस धारणा के तहत हूं कि यह वास्तव में जटिलता (एन -1 अधिक कक्षाएं) जोड़ता है, जिसमें एक परीक्षण पास करने के अलावा कोई लाभ नहीं है। मैं निश्चित रूप से पकड़ सकता हूं कि CarWithFrontSeatsInstalled और CarWithAllSeatsInstalled तार्किक रूप से क्रमिक चरण हैं। अल्फा द्वारा बाद में आवश्यक ब्रावो पद्धति का जोखिम छोटा है, और अगर मैं इसे अच्छी तरह से खेलता हूं तो भी छोटा होता है। फिर भी।
  • मैं एक ही बार में, अलग-अलग ऑपरेशनों को एक समान कर सकता हूं। performAllSeatsInstallation()। यह केवल एक स्टॉपगैप उपाय है और यह एकल ऑपरेशन की जटिलता को बढ़ाता है। अगर मुझे कभी भी एक अलग क्रम में ए और बी ऑपरेशन करने की आवश्यकता होती है, और मैंने उन्हें ई = (ए + सी) और एफ (बी + डी) के अंदर पैक किया है, तो मुझे ई और एफ को अनबंड करना होगा और कोड को फेरबदल करना होगा ।
  • मैं मेमने के कार्यों की एक सरणी का उपयोग कर सकता हूं और पूरी तरह से जांच को दरकिनार कर सकता हूं, लेकिन मुझे लगता है कि यह क्लंकी है। हालांकि यह अब तक का सबसे अच्छा विकल्प है। यह प्रतिबिंब से छुटकारा मिलेगा। मेरे पास जो दो समस्याएं हैं, मुझे शायद सभी विधि वस्तुओं को फिर से लिखने के लिए कहा जाएगा , न केवल काल्पनिक CarWithEngineInstalled, और जबकि यह बहुत अच्छी नौकरी की सुरक्षा होगी, यह वास्तव में यह सब अपील नहीं करता है; और यह कि कोड कवरेज चेकर के पास लैम्ब्डा (जो हल करने योग्य हैं, लेकिन फिर भी ) के साथ समस्याएँ हैं ।

इसलिए...

  • जो, आपको लगता है, मेरा सबसे अच्छा विकल्प है?
  • क्या कोई बेहतर तरीका है जिस पर मैंने विचार नहीं किया है? ( शायद मैं बेहतर ढंग से साफ आऊंगा और सीधे पूछूंगा कि यह क्या है? )
  • क्या यह डिज़ाइन निराशाजनक रूप से दोषपूर्ण है, और मैं हार और खाई को बेहतर स्वीकार करूँगा - यह वास्तुकला पूरी तरह से? मेरे करियर के लिए अच्छा नहीं है, लेकिन लंबी अवधि में बीमार डिजाइन कोड लिखना बेहतर होगा?
  • क्या मेरी वर्तमान पसंद वास्तव में वन ट्रू वे है, और मुझे बेहतर गुणवत्ता वाले मेट्रिक्स (और / या इंस्ट्रूमेंटेशन) स्थापित करने के लिए लड़ने की जरूरत है? इस अंतिम विकल्प के लिए मुझे संदर्भों की आवश्यकता होगी ... मैं बड़बड़ाते समय @PHB पर अपना हाथ नहीं हिला सकता, ये वे मीट्रिक नहीं हैं जिनकी आप तलाश कर रहे हैंकोई फर्क नहीं पड़ता कि मैं कितना सक्षम होना चाहता हूं

3
या, आप "अधिक से अधिक जटिलता" चेतावनी को अनदेखा कर सकते हैं।
रॉबर्ट हार्वे

अगर मैं कर सकता तो मैं करता। किसी भी तरह इस मेट्रिक्स चीज़ ने एक पवित्र गुणवत्ता हासिल कर ली है। मैं पीटीबी को एक उपयोगी उपकरण के रूप में स्वीकार करने के लिए प्रयास करने और समझाने के लिए जारी रख रहा हूं, लेकिन केवल एक उपकरण। मैं अभी तक सफल हो सकता हूँ ...
LSerni

क्या ऑपरेशन वास्तव में एक ऑब्जेक्ट का निर्माण कर रहे हैं, या आप सिर्फ असेंबली लाइन रूपक का उपयोग कर रहे हैं क्योंकि यह आपके द्वारा उल्लिखित विशिष्ट संपत्ति को साझा करता है (एक आंशिक निर्भरता क्रम के साथ कई ऑपरेशन)? महत्व यह है कि पूर्व बिल्डर पैटर्न का सुझाव देता है, जबकि उत्तरार्द्ध में भरे गए अधिक विवरण के साथ कुछ अन्य पैटर्न का सुझाव दे सकता है।
outis

2
मैट्रिक्स का अत्याचार। मेट्रिक्स उपयोगी संकेतक हैं, लेकिन उन्हें इस बात की अनदेखी करते हुए कि मीट्रिक का उपयोग क्यों किया जाता है, मददगार नहीं है।
Jaydee

2
आवश्यक जटिलता और आकस्मिक जटिलता के बीच अंतर को लोगों को समझाएं। en.wikipedia.org/wiki/No_Silver_Bullet यदि आप सुनिश्चित करते हैं कि नियम को तोड़ने वाली जटिलता जरूरी है, तो यदि आप प्रति प्रोग्रामर प्रतिशोधक हैं। जटिलता बाहर। यदि चरणों में चीजों को इनकैप्सुलेट करना मनमाना नहीं है (चरण समस्या से संबंधित हैं) और रीडायरेक्टर कोड को बनाए रखने वाले डेवलपर्स के लिए संज्ञानात्मक भार को कम करता है, तो यह ऐसा करने के लिए समझ में आता है।
फुहरामैन

जवाबों:


15

संचालन का लंबा अनुक्रम ऐसा लगता है कि यह अपना वर्ग होना चाहिए, जिसे तब अपने कर्तव्यों को निभाने के लिए अतिरिक्त वस्तुओं की आवश्यकता होती है। ऐसा लगता है कि आप इस समाधान के करीब हैं। इस लंबी प्रक्रिया को कई चरणों या चरणों में तोड़ा जा सकता है। प्रत्येक चरण या चरण का अपना वर्ग हो सकता है जो सार्वजनिक पद्धति को उजागर करता है। आप चाहते हैं कि प्रत्येक चरण समान इंटरफ़ेस लागू करे। फिर आपकी असेंबली लाइन चरणों की एक सूची का ट्रैक रखती है।

अपनी कार असेंबली उदाहरण पर निर्माण करने के लिए, Carकक्षा की कल्पना करें :

public class Car
{
    public IChassis Chassis { get; private set; }
    public Dashboard { get; private set; }
    public IList<Seat> Seats { get; private set; }

    public Car()
    {
        Seats = new List<Seat>();
    }

    public void AddChassis(IChassis chassis)
    {
        Chassis = chassis;
    }

    public void AddDashboard(Dashboard dashboard)
    {
        Dashboard = dashboard;
    }
}

मैं कुछ घटकों के कार्यान्वयन को छोड़ने जा रहा हूं, जैसे IChassis, Seatऔर Dashboardसंक्षिप्तता के लिए।

Carखुद के निर्माण के लिए ज़िम्मेदार नहीं है। असेंबली लाइन है, तो चलिए इसे एक वर्ग में शामिल करते हैं:

public class CarAssembler
{
    protected List<IAssemblyPhase> Phases { get; private set; }

    public CarAssembler()
    {
        Phases = new List<IAssemblyPhase>()
        {
            new ChassisAssemblyPhase(),
            new DashboardAssemblyPhase(),
            new SeatAssemblyPhase()
        };
    }

    public void Assemble(Car car)
    {
        foreach (IAssemblyPhase phase in Phases)
        {
            phase.Assemble(car);
        }
    }
}

यहां महत्वपूर्ण अंतर यह है कि CarAssembler में विधानसभा चरण ऑब्जेक्ट्स की एक सूची है जो लागू करते हैं IAssemblyPhase। अब आप सार्वजनिक तरीकों से स्पष्ट रूप से काम कर रहे हैं, जिसका अर्थ है कि प्रत्येक चरण का परीक्षण स्वयं द्वारा किया जा सकता है, और आपका कोड गुणवत्ता उपकरण अधिक खुश है क्योंकि आप एक एकल वर्ग में इतना भर नहीं कर रहे हैं। असेंबली प्रक्रिया सरल है। बस चरणों में पाश और Assembleकार में गुजर कॉल । किया हुआ। IAssemblyPhaseइंटरफ़ेस भी सिर्फ एक सार्वजनिक विधि है कि एक कार वस्तु लेता है के साथ मृत सरल है:

public interface IAssemblyPhase
{
    void Assemble(Car car);
}

अब हमें अपने ठोस वर्गों को प्रत्येक विशिष्ट चरण के लिए इस इंटरफ़ेस को लागू करने की आवश्यकता है:

public class ChassisAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        car.AddChassis(new UnibodyChassis());
    }
}

public class DashboardAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        Dashboard dashboard = new Dashboard();

        dashboard.AddComponent(new Speedometer());
        dashboard.AddComponent(new FuelGuage());
        dashboard.Trim = DashboardTrimType.Aluminum;

        car.AddDashboard(dashboard);
    }
}

public class SeatAssemblyPhase : IAssemblyPhase
{
    public void Assemble(Car car)
    {
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
        car.Seats.Add(new Seat());
    }
}

प्रत्येक चरण व्यक्तिगत रूप से बहुत सरल हो सकता है। कुछ सिर्फ एक लाइनर हैं। कुछ बस चार सीटों को जोड़कर अंधा कर सकते हैं, और दूसरे को कार में जोड़ने से पहले डैशबोर्ड को कॉन्फ़िगर करना होगा। इस लंबी खींची गई प्रक्रिया की जटिलता कई, पुन: प्रयोज्य वर्गों में विभाजित है जो आसानी से परीक्षण योग्य हैं।

भले ही आपने कहा था कि आदेश अभी मायने नहीं रखता है, यह भविष्य में हो सकता है।

इसे समाप्त करने के लिए, आइए एक कार को असेंबल करने की प्रक्रिया देखें:

Car car = new Car();
CarAssembler assemblyLine = new CarAssembler();

assemblyLine.Assemble(car);

आप एक विशिष्ट प्रकार की कार, या ट्रक को इकट्ठा करने के लिए CarAssembler को उप वर्ग कर सकते हैं। प्रत्येक चरण एक बड़ी पूरी के भीतर एक इकाई है, जिससे कोड का पुन: उपयोग करना आसान हो जाता है।


क्या यह डिजाइन निराशाजनक रूप से त्रुटिपूर्ण है, और मैं हार और खाई को बेहतर मानता हूं - यह वास्तुकला पूरी तरह से? मेरे करियर के लिए अच्छा नहीं है, लेकिन लंबी अवधि में बीमार डिजाइन कोड लिखना बेहतर होगा?

यदि मैंने जो लिखा है उसे फिर से लिखने की जरूरत है, यह तय करना कि मेरे करियर पर एक काला निशान था, तो मैं अभी एक खाई खोदने का काम करूंगा, और आपको मेरी कोई सलाह नहीं लेनी चाहिए। :)

सॉफ्टवेयर इंजीनियरिंग सीखने, आवेदन करने और फिर से सीखने की एक शाश्वत प्रक्रिया है। सिर्फ इसलिए कि आप अपने कोड को फिर से लिखने का फैसला करते हैं इसका मतलब यह नहीं है कि आप निकाल देंगे। अगर ऐसा होता तो कोई सॉफ्टवेयर इंजीनियर नहीं होता।

क्या मेरी वर्तमान पसंद वास्तव में वन ट्रू वे है, और मुझे बेहतर गुणवत्ता वाले मेट्रिक्स (और / या इंस्ट्रूमेंटेशन) स्थापित करने के लिए लड़ने की जरूरत है?

आपने जो बताया है, वह वन ट्रू वे नहीं है, हालाँकि यह ध्यान रखें कि कोड मेट्रिक्स भी वन ट्रू वे नहीं हैं। कोड मेट्रिक्स को चेतावनी के रूप में देखा जाना चाहिए। वे भविष्य में रखरखाव की समस्याओं को इंगित कर सकते हैं। वे दिशा-निर्देश हैं, कानून नहीं। अगर यह ठीक से लागू करता है देखने के लिए अपने कोड मैट्रिक्स उपकरण अंक कुछ बाहर, मैं पहली बार कोड की जांच करेगा जब ठोस प्रिंसिपलों। कई बार इसे और अधिक ठोस बनाने के लिए कोड को फिर से भरना कोड मैट्रिक्स टूल को संतुष्ट करेगा। कभी-कभी ऐसा नहीं होता। आपको इन मेट्रिक्स को केस बेसिस पर केस में लेना होगा।


1
हाँ, बहुत बेहतर है तो एक देव वर्ग है।
भाग 1

यह दृष्टिकोण काम करता है, लेकिन ज्यादातर इसलिए कि आप मापदंडों के बिना कार के लिए तत्व प्राप्त कर सकते हैं। यदि आपको उन्हें पास करने की आवश्यकता हो तो क्या होगा? फिर आप यह सब खिड़की से बाहर फेंक सकते हैं और पूरी तरह से इस प्रक्रिया को पुनर्विचार कर सकते हैं, क्योंकि आप वास्तव में 150 मापदंडों वाले कार कारखाने नहीं हैं, यह पागल है।
एंडी

@DavidPacker: यहां तक ​​कि अगर आपको सामान का एक गुच्छा परिमाणित करना चाहिए, तो आप उसे किसी तरह के कॉन्फिगरेशन वर्ग में एन्कोड कर सकते हैं जिसे आप अपने "असेंबलर" ऑब्जेक्ट के कंस्ट्रक्टर में पास करते हैं। इस कार उदाहरण में, पेंट का रंग, आंतरिक रंग और सामग्री, ट्रिम पैकेज, इंजन, और बहुत कुछ अनुकूलित किया जा सकता है, लेकिन आपके पास 150 अनुकूलन नहीं होंगे। आपके पास संभवतः एक दर्जन या तो होगा, जो एक विकल्प ऑब्जेक्ट को उधार देता है।
ग्रेग बर्गार्ड्ट

लेकिन केवल कॉन्फ़िगरेशन को जोड़ने से लूप के लिए सुंदर के उद्देश्य की अवहेलना होगी, जो एक जबरदस्त शर्म की बात है, क्योंकि आपको कॉन्फ़िगरेशन को पार्स करना होगा और इसे उचित तरीकों को असाइन करना होगा जो बदले में आपको उचित ऑब्जेक्ट देगा। तो आप शायद मूल डिजाइन क्या था के साथ काफी कुछ इसी तरह खत्म हो जाएगा।
एंडी

समझा। एक कक्षा और पचास तरीके होने के बजाय, मैं वास्तव में पचास कोडांतरक दुबला वर्ग और एक ऑर्केस्ट्रेटिंग क्लास होगा। अंत में परिणाम समान लगता है, प्रदर्शन वार भी, लेकिन कोड लेआउट क्लीनर है। मुझें यह पसंद है। यह ऑपरेशनों को जोड़ने के लिए थोड़ा और अधिक अजीब होगा (मुझे उन्हें अपनी कक्षा में स्थापित करना होगा, साथ ही ऑर्क्रेटिंग क्लास को सूचित करना होगा; मुझे इस आवश्यकता से बाहर निकलने का कोई आसान तरीका नहीं दिखता), लेकिन फिर भी मुझे यह बहुत पसंद है। मुझे इस दृष्टिकोण का पता लगाने के लिए कुछ दिनों की अनुमति दें।
LSerni

1

मुझे नहीं पता कि यह आपके लिए संभव है, लेकिन मैं अधिक डेटा उन्मुख दृष्टिकोण का उपयोग करने के बारे में सोचूंगा। विचार यह है कि आप नियमों और बाधाओं, संचालन, निर्भरता, राज्य, आदि की कुछ (घोषणापत्र) अभिव्यक्ति पर कब्जा कर लेते हैं ... फिर आपके वर्ग और कोड अधिक सामान्य होते हैं, नियमों का पालन करने के लिए उन्मुख होते हैं, उदाहरणों की वर्तमान स्थिति को शुरू करते हैं, संचालन करते हैं नियम को बदलने के लिए, नियमों के घोषणात्मक कैप्चर का उपयोग करके और कोड को अधिक सीधे उपयोग करने के बजाय राज्य में परिवर्तन। एक प्रोग्रामिंग भाषा में डेटा घोषणाओं का उपयोग कर सकता है, या, कुछ डीएसएल टूलिंग, या एक नियम या तर्क इंजन।


कुछ संचालन वास्तव में इस तरह से लागू होते हैं (नियमों की सूची के रूप में)। कार के उदाहरण के साथ रखने के लिए, फ़्यूज़, रोशनी और प्लग का एक बॉक्स स्थापित करते समय मैं वास्तव में तीन अलग-अलग तरीकों का उपयोग नहीं करता हूं, लेकिन केवल एक, जो सामान्य रूप से दो-पिन विद्युत चीज़ामाजिग्स को जगह में फिट करता है, और तीन फ़्यूज़ की सूची लेता है। , रोशनी, और प्लग। अन्य तरीकों के महान बहुमत दुर्भाग्य से आसानी से इस दृष्टिकोण के लिए उत्तरदायी नहीं हैं।
LSerni

1

किसी तरह समस्या मुझे निर्भरता की याद दिलाती है। आप एक विशिष्ट कॉन्फ़िगरेशन में कार चाहते हैं। ग्रेग बर्गहार्ट की तरह, मैं प्रत्येक चरण / आइटम / के लिए ऑब्जेक्ट्स / कक्षाओं के साथ जाऊंगा।

प्रत्येक चरण घोषणा करता है कि यह मिश्रण में क्या जोड़ता है (यह क्या है provides) (कई चीजें हो सकती हैं), लेकिन यह भी कि इसके लिए क्या आवश्यक है।

फिर, आप अंतिम आवश्यक कॉन्फ़िगरेशन को कहीं और परिभाषित करते हैं, और एक एल्गोरिथ्म होता है जो आपकी ज़रूरत को देखता है, और यह तय करता है कि किन चरणों को निष्पादित करने की आवश्यकता है / किन भागों को जोड़ने की आवश्यकता है / जो दस्तावेजों को इकट्ठा करने की आवश्यकता है।

निर्भरता रिज़ॉल्यूशन एल्गोरिदम उतना कठिन नहीं है। सबसे सरल मामला वह है जहां प्रत्येक चरण एक चीज प्रदान करता है, और कोई भी दो चीजें एक ही चीज प्रदान नहीं करती हैं, और निर्भरताएं सरल हैं (निर्भरता में कोई 'या' नहीं)। अधिक जटिल मामलों के लिए: बस डेबियन एप्ट या कुछ और जैसे उपकरण को देखें।

अंत में, अपनी कार का निर्माण तब कम हो जाता है कि वहाँ क्या संभव कदम हैं, और CarBuilder को बताए गए चरणों की आवश्यकता है।

हालांकि एक महत्वपूर्ण बात यह है कि आपको CarBuilder को सभी चरणों के बारे में बताने का तरीका खोजना होगा। कॉन्फ़िगरेशन फ़ाइल का उपयोग करके ऐसा करने का प्रयास करें। एक अतिरिक्त कदम जोड़ना तब केवल विन्यास फाइल के अतिरिक्त की आवश्यकता होगी। यदि आपको तर्क की आवश्यकता है, तो कॉन्फ़िगर फ़ाइल में एक डीएसएल जोड़ने का प्रयास करें। यदि अन्य सभी विफल हो जाते हैं, तो आप उन्हें कोड में परिभाषित कर रहे हैं।


0

जिन चीजों का आप उल्लेख करते हैं उनमें से एक जोड़ी मेरे लिए 'बुरी' है

"मेरा तर्क वर्तमान में कार्यान्वयन की सादगी के लिए प्रतिबिंब का उपयोग करता है"

वास्तव में इसके लिए कोई बहाना नहीं है। क्या आप वास्तव में विधि नामों की स्ट्रिंग तुलना का उपयोग कर रहे हैं यह निर्धारित करने के लिए कि क्या चलाना है ?! यदि आप आदेश बदलते हैं तो आपको विधि का नाम बदलना होगा ?!

"एक ही चरण में संचालन पहले से ही स्वतंत्र हैं"

यदि वे वास्तव में एक-दूसरे से स्वतंत्र हैं तो यह बताता है कि आपकी कक्षा ने एक से अधिक जिम्मेदारी ली है। मेरे लिए, आपके दोनों उदाहरण किसी न किसी प्रकार के ऋण देने के लिए हैं

MyObject.AddComponent(IComponent component) 

दृष्टिकोण जो आपको प्रत्येक अपवर्ग के तर्क को अपने स्वयं के वर्ग या कक्षाओं में विभाजित करने की अनुमति देगा।

वास्तव में मुझे लगता है कि वे वास्तव में स्वतंत्र नहीं हैं, मैं कल्पना करता हूं कि प्रत्येक वस्तु की स्थिति की जांच करता है और इसे संशोधित करता है, या कम से कम शुरू होने से पहले किसी प्रकार का सत्यापन करता है।

इस मामले में आप या तो कर सकते हैं:

  1. ओओपी को खिड़की से बाहर फेंक दें, और ऐसी सेवाएं हैं जो आपकी कक्षा में उजागर डेटा पर काम करती हैं।

    Service.AddDoorToCar (कार कार)

  2. एक बिल्डर वर्ग है जो पहले आवश्यक डेटा को इकट्ठा करके और पूरी की गई वस्तु को वापस करके आपकी वस्तु का निर्माण करता है।

    कार = CarBuilder.ODoor ()। WithDoor ()। WithWheels ();

(withX तर्क को फिर से उप-निर्माताओं में विभाजित किया जा सकता है)

  1. क्रियात्मक दृष्टिकोण अपनाएं और एक संशोधित विधि में फ़ंक्शन / डेलगेट्स पास करें

    कार.मोडिफाइ ((c) => c.rl ++);


इवान ने कहा: "ओओआर को खिड़की से बाहर फेंक दें, और आपकी कक्षा में उजागर डेटा पर काम करने वाली सेवाएं हैं" --- यह ऑब्जेक्ट-ओरिएंटेड नहीं है?
ग्रेग बरगार्ड

?? इसका नहीं, इसका एक गैर OO विकल्प
Ewan

आप ऑब्जेक्ट का उपयोग कर रहे हैं, जिसका अर्थ है कि यह "ऑब्जेक्ट ओरिएंटेड" है। सिर्फ इसलिए कि आप अपने कोड के लिए एक प्रोग्रामिंग पैटर्न की पहचान नहीं कर सकते हैं इसका मतलब यह नहीं है कि यह ऑब्जेक्ट ओरिएंटेड नहीं है। एसओएलआईडी सिद्धांत एक अच्छा नियम है। यदि आप कुछ या सभी ठोस सिद्धांतों को लागू करते हैं, तो यह ऑब्जेक्ट ओरिएंटेड है। वास्तव में, यदि आप वस्तुओं का उपयोग कर रहे हैं और विभिन्न प्रक्रियाओं या स्थैतिक तरीकों के आसपास सिर्फ पासिंग स्ट्रक्चर नहीं है, तो यह ऑब्जेक्ट ओरिएंटेड है। "ऑब्जेक्ट ओरिएंटेड कोड" और "गुड कोड" के बीच अंतर है। आप खराब ऑब्जेक्ट ओरिएंटेड कोड लिख सकते हैं।
ग्रेग बर्गार्ड्ट

इसका 'ओओ नहीं' क्योंकि आप डेटा को उजागर कर रहे हैं जैसे कि यह एक संरचना थी और एक अलग कक्षा में एक प्रक्रिया के रूप में इस पर काम कर रही थी
इवान

tbh मैंने केवल अपरिहार्य "OOP नहीं!" टिप्पणियाँ
इवान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.