ईवल इज एविल
सबसे पहले:eval()
का इस्तेमाल न करें जब तक कोई अच्छा कारण न हो। और कभी कोई अच्छा कारण नहीं होता ।
सबसे खराब स्थिति में eval()
आपके एप्लिकेशन को इंजेक्शन के हमलों के प्रति संवेदनशील बनाता है और यह बहुत धीमा भी है। थोड़े से शोध से कई कारणों का पता चलता है कि क्यों eval एक बड़ी संख्या नहीं है।
अपना गणना कोड डेटाबेस में सेव न करें
यदि आप ऐसा करते हैं और आप PHP से दूसरी भाषा में स्विच करना चाहते हैं तो आपके पास अभी भी आपके डेटाबेस में PHP कोड होगा। इससे भाषाओं को माइग्रेट करना वाकई मुश्किल हो जाता है। आपको हमेशा अपने आवेदन के अधिक से अधिक हिस्सों को यथासंभव स्वतंत्र बनाने का प्रयास करना चाहिए।
इस मामले में आप डेटाबेस में उपयोग की जाने वाली भाषा को कसकर जोड़ देंगे। यह एक बुरा अभ्यास है।
साथ ही डेटाबेस से आपकी गणनाओं को चलाने की एकमात्र संभावनाएं उन्हें eval करना होगा (जो खराब है, ऊपर देखें) या स्ट्रिंग ऑपरेशंस या रेगेक्स के साथ स्ट्रिंग को अलग करना जो अनावश्यक प्रयास का कारण बनता है।
यह सब रणनीति के बारे में है
अपनी समस्या को हल करने के लिए आपको कोड को निष्पादित करना होगा जो इस बात पर निर्भर करता है कि आपको किस गणना की आवश्यकता है। यह या तो स्विच-केस-स्टेटमेंट या इफ-स्टेटमेंट के साथ किया जा सकता है। लेकिन यह भी एक बहुत ही सुंदर समाधान नहीं है। कल्पना कीजिए कि भविष्य में गणना करने से पहले आपको अन्य संचालन निष्पादित करने की आवश्यकता होगी, या कार्यक्षमता का विस्तार करना होगा। आपको अपने सभी मामलों या अगर-बयानों को अपडेट करना होगा।
एक अच्छा डिज़ाइन-पैटर्न है जिसे रणनीति पैटर्न कहा जाता है। . रणनीति पैटर्न समस्याओं को हल करता है जब एक उपयोग-मामले को अलग तरीके से संभाला जा सकता है जो शायद आप चाहते हैं।
आप कुछ (उपयोग-मामले) की गणना करना चाहते हैं और इसके लिए अलग-अलग गणना प्रकार हैं (अलग-अलग रणनीतियां)
यह कैसे काम करता है
रणनीति पैटर्न को लागू करने के लिए आपको मूल रूप से तीन चीजों की आवश्यकता होती है।
- एक वर्ग जहां आप अपनी रणनीतियों को इंजेक्ट करते हैं। यह मूल रूप से आपके रणनीति कार्यों के लिए एक आवरण है।
- एक इंटरफ़ेस जो आपकी रणनीतियों द्वारा कार्यान्वित किया जाएगा
- आपकी रणनीतियाँ
आपका इंटरफ़ेस इस तरह दिख सकता है:
<?php
interface CalculatableInterface {
public function calculate();
}
इंटरफ़ेस यह सुनिश्चित करेगा कि आपकी सभी रणनीतियाँ वास्तव में गणना चलाने के लिए एक विधि प्रदान करती हैं। कुछ खास नहीं।
इसके बाद आप एक आधार वर्ग चाहते हैं जो आपके गणना ऑपरेटरों को कंस्ट्रक्टर तर्क के रूप में लेता है और उन्हें गुणों में संग्रहीत करता है।
<?php
abstract class Calculatable {
protected $valueA;
protected $valueB;
public function __construct($valueA, $valueB)
{
$this->valueA = $valueA;
$this->valueB = $valueB;
}
}
अब यह गंभीर हो रहा है। हम अपनी रणनीतियों को लागू कर रहे हैं।
<?php
class Division extends Calculatable implements CalculatableInterface {
public function calculate()
{
return ($this->valueB != 0) ? $this->valueA / $this->valueB : 'NA';
}
}
class Percentage extends Calculatable implements CalculatableInterface {
public function calculate()
{
return ($this->valueB != 0) ? (100 / $this->valueB) * $this->valueA : 'NA';
}
}
बेशक आप इसे थोड़ा साफ कर सकते हैं, लेकिन मैं यहां जो बताना चाहता हूं वह है क्लास डिक्लेरेशन।
हम अपने Calculatable
. का विस्तार कर रहे हैं वर्ग ताकि हम कंस्ट्रक्टर के माध्यम से अंकगणितीय संचालन पास कर सकें और हम CalculatableInterface
. को लागू कर रहे हैं जो हमारी कक्षा को बताता है:"अरे! आपको एक गणना विधि प्रदान करनी होगी, मुझे परवाह नहीं है कि आप चाहते हैं या नहीं।
हम बाद में देखेंगे कि यह पैटर्न का एक अभिन्न अंग क्यों है।
तो हमारे पास दो ठोस वर्ग हैं जिनमें वास्तविक अंकगणितीय ऑपरेशन के लिए वास्तविक कोड होता है। यदि आपको कभी आवश्यकता हो, तो आप इसे आसानी से बदल सकते हैं जैसा कि आप देखते हैं। अधिक संचालन जोड़ने के लिए बस एक और वर्ग जोड़ें।
अब हम एक ऐसा वर्ग बनाएंगे जहां हमारी रणनीतियों को इंजेक्ट किया जा सके। बाद में आप इस वर्ग के किसी ऑब्जेक्ट को इंस्टेंट करेंगे और उसके साथ काम करेंगे।
यह इस तरह दिखता है:
<?php
class Calculator {
protected $calculatable;
public function __construct( CalculatableInterface $calculatable )
{
$this->calculatable = $calculatable;
}
public function calculate()
{
return $this->calculatable->calculate();
}
}
यहां सबसे महत्वपूर्ण हिस्सा कंस्ट्रक्टर है। देखें कि हम यहां अपने इंटरफ़ेस को कैसे टाइप-हिंट करते हैं। ऐसा करने से हम सुनिश्चित करते हैं कि केवल एक वस्तु को इंजेक्ट किया जा सकता है (निर्भरता इंजेक्शन ) जिसका वर्ग इंटरफ़ेस लागू करता है . हमें यहां ठोस वर्ग की मांग करने की जरूरत नहीं है। यही यहाँ महत्वपूर्ण बिंदु है।
इसके अलावा वहाँ एक गणना विधि है। गणना पद्धति को निष्पादित करने की हमारी रणनीति के लिए यह सिर्फ एक आवरण है।
इसे लपेटना
तो अब हमें बस अपने Calculator
. का एक ऑब्जेक्ट बनाने की जरूरत है क्लास और हमारे रणनीति वर्गों में से एक का ऑब्जेक्ट पास करें (जिसमें अंकगणितीय संचालन के लिए कोड होता है)।
<?php
//The corresponding string is stored in your DB
$calculatable = 'Division';
$calc = new Calculator( new $calculatable(15, 100) );
echo $calc->calculate();
$calculatable
. में संग्रहीत स्ट्रिंग को बदलने का प्रयास करें से Percentage
और आप देखते हैं कि प्रतिशत की गणना के लिए ऑपरेशन निष्पादित किया जाएगा।
निष्कर्ष
रणनीति पैटर्न ने आपको गतिशील कार्यों के साथ काम करने के लिए एक स्वच्छ इंटरफ़ेस बनाने की अनुमति दी है जो केवल रनटाइम के दौरान ठोस होते हैं। न तो आपके डेटाबेस को यह जानने की जरूरत है कि हम चीजों की गणना कैसे करते हैं, और न ही आपका वास्तविक कैलकुलेटर करता है। केवल एक चीज जिसे हमें सुनिश्चित करने की आवश्यकता है वह है इंटरफ़ेस के विरुद्ध कोड जो हमें चीजों की गणना करने की एक विधि प्रदान करता है।