इंटरफ़ेस स्थिरांक के पेशेवरों और विपक्ष [बंद]


105

PHP इंटरफेस एक इंटरफ़ेस में स्थिरांक की परिभाषा की अनुमति देता है, जैसे

interface FooBar
{
    const FOO = 1;
    const BAR = 2;
}
echo FooBar::FOO; // 1

किसी भी कार्यान्वयन वर्ग में ये स्थिरांक स्वतः उपलब्ध होंगे, जैसे

class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1

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

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

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


1
हम्म, मैं एक इंटरफेस में स्थिरांक को परिभाषित करने की आवश्यकता से पहले कभी नहीं आऊंगा। यह जानने योग्य है कि इंटरफ़ेस को लागू करने वाली कक्षाएं स्थिरांक को ओवरराइड नहीं कर सकती हैं, जबकि कक्षाएं केवल एक दूसरे को विस्तारित करने से स्थिरांक को ओवरराइड कर सकती हैं।
चार्ल्स

1
मेरा मानना ​​है कि स्थिरांक खराब नहीं होते हैं क्योंकि उनके पास अनुमानित मान हैं जब हम इकाई परीक्षण के साथ संबंध रखते हैं। वैश्विक चर बुरे हैं क्योंकि कोई भी इसे बदल सकता है क्योंकि यह एक चर है और सब कुछ इस पर गुंजाइश है लेकिन स्थिरांक कभी भी इसके मूल्य को नहीं बदलेंगे।
mdprotacio 19

जवाबों:


135

खैर, मुझे लगता है कि यह अच्छे और अच्छे के बीच के अंतर को उबालता है

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

खराब:

interface User {
    const TYPE_ADMINISTRATOR = 1;
    const TYPE_USER          = 2;
    const TYPE_GUEST         = 3;
}

काफी है:

interface HTTPRequest_1_1 {
    const TYPE_CONNECT = 'connect';
    const TYPE_DELETE  = 'delete';
    const TYPE_GET     = 'get';
    const TYPE_HEAD    = 'head';
    const TYPE_OPTIONS = 'options';
    const TYPE_POST    = 'post';
    const TYPE_PUT     = 'put';

    public function getType();
}

अब, मैंने उन उदाहरणों को चुना है जो सरल है। Userइंटरफ़ेस उपयोगकर्ता प्रकार का एक enum को परिभाषित किया गया है। यह समय के साथ विस्तारित होने की बहुत संभावना है और किसी अन्य पैटर्न द्वारा बेहतर अनुकूल होगा। लेकिन HTTPRequest_1_1एक सभ्य उपयोग-मामला है, क्योंकि एनएफसी RFC2616 द्वारा परिभाषित किया गया है और वर्ग के जीवनकाल के लिए नहीं बदलेगा।

सामान्य तौर पर, मैं एक वैश्विक समस्या होने के रूप में स्थिरांक और वर्ग के साथ समस्या को नहीं देखता हूं । मैं इसे एक निर्भरता समस्या के रूप में देखता हूं। यह एक संकीर्ण भेद है, लेकिन एक निश्चित है। मैं वैश्विक समस्याओं को वैश्विक चर के रूप में देखता हूं जो लागू नहीं होते हैं, और जैसे कि एक नरम वैश्विक निर्भरता पैदा करते हैं। लेकिन एक हार्ड-कोडेड क्लास एक लागू निर्भरता बनाता है, और जैसे कि एक कठिन वैश्विक निर्भरता बनाता है। तो दोनों निर्भरताएं हैं। लेकिन मैं इसे लागू नहीं होने के कारण वैश्विक रूप से बहुत बुरा मानता हूं ... यही कारण है कि मैं एक ही बैनर के तहत वैश्विक निर्भरता के साथ वर्ग निर्भरता को लुप्त करना पसंद नहीं करता ...

यदि आप लिखते हैं MyClass::FOO, तो आप कार्यान्वयन के विवरण के लिए कठिन-कोडित हैं MyClass। यह एक हार्ड-युग्मन बनाता है, जो आपके कोड को कम लचीला बनाता है, और इस तरह से बचा जाना चाहिए। हालाँकि, इस प्रकार के युग्मन की अनुमति देने के लिए इंटरफेस मौजूद हैं। इसलिए MyInterface::FOOकिसी भी ठोस युग्मन का परिचय नहीं है। इसके साथ ही मैंने कहा कि मैं इसमें निरंतरता जोड़ने के लिए केवल एक अंतरफलक नहीं पेश करूंगा।

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

फिर, उस पर सिर्फ मेरा विचार है ...


4
आप इस मामले में उपयोगकर्ता के लिए एक अलग पैटर्न के रूप में क्या सुझाव देंगे?
याकूब

@ जैकब: मैं इसे दूर करूंगा। आपकी आवश्यकताओं के आधार पर, मैं संभवतः एक एक्सेस क्लास का निर्माण करूंगा जो डेटाबेस तालिका से अपना डेटा प्राप्त करेगा। इस तरह एक नया स्तर जोड़ना उतना ही आसान है जितना कि नई पंक्ति को सम्मिलित करना। एक और विकल्प एक ENUM वर्ग सेट (जहां आपके पास प्रत्येक अनुमति भूमिका के लिए एक वर्ग है) का निर्माण करना होगा। फिर आप उन कक्षाओं का विस्तार कर सकते हैं जहां उपयुक्त अनुमति प्रदान करना आवश्यक है। लेकिन अन्य तरीके भी हैं जो काम करेंगे
ircmaxell

3
बहुत ठोस और अच्छी तरह से स्पष्ट जवाब! +1
डिसेंट डब्बल

1
सार्वजनिक स्थिरांक वाले वर्ग के पास कोई विधि नहीं होनी चाहिए। यह केवल डेटा संरचना या केवल ऑब्जेक्ट होना चाहिए - दोनों नहीं।
OZ_

2
@FrederikKrautwald: आप बहुरूपता (ज्यादातर मामलों में) के साथ सशर्त से बच सकते हैं: इस उत्तर की जाँच करें और साथ ही साथ इस क्लीन कोड पर बात करें ...
ircmaxell

10

मुझे लगता है कि अपने इंटरफ़ेस से एक अलग प्रकार ("वर्ग") के रूप में, स्थिरांक, विशेष रूप से संचित स्थिरांक को संभालना आमतौर पर बेहतर होता है:

define(TYPE_CONNECT, 'connect');
define(TYPE_DELETE , 'delete');
define(TYPE_GET    , 'get');
define(TYPE_HEAD   , 'head');
define(TYPE_OPTIONS, 'options');
define(TYPE_POST   , 'post');
define(TYPE_PUT    , 'put');

interface IFoo
{
  function /* int */ readSomething();
  function /* void */ ExecuteSomething(/* int */ param);
}

class CBar implements IFoo
{
  function /* int */ readSomething() { ...}
  function /* void */ ExecuteSomething(/* int */ param) { ... }
}

या, यदि आप नाम के रूप में एक वर्ग का उपयोग करना चाहते हैं:

class TypeHTTP_Enums
{
  const TYPE_CONNECT = 'connect';
  const TYPE_DELETE  = 'delete';
  const TYPE_GET     = 'get';
  const TYPE_HEAD    = 'head';
  const TYPE_OPTIONS = 'options';
  const TYPE_POST    = 'post';
  const TYPE_PUT     = 'put';
}

interface IFoo
{
  function /* int */ readSomething();
  function /* void */ ExecuteSomething(/* int */ param);
}

class CBar implements IFoo
{
  function /* int */ readSomething() { ...}
  function /* void */ ExecuteSomething(/* int */ param) { ... }
}

यह नहीं है कि आप केवल स्थिरांक का उपयोग कर रहे हैं, आप प्रगणित मूल्यों या गणना की अवधारणा का उपयोग कर रहे हैं, जो एक विशिष्ट मूल्यों के एक सेट को एक विशिष्ट उपयोग ("डोमेन") के साथ माना जाता है?

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