लारवेल के साथ एकल जिम्मेदारी सिद्धांत (एसआरपी)

एसआरपी सिद्धांत (एक जिम्मेदारी सिद्धांत) समर्थित कोड लिखने के मूलभूत सिद्धांतों में से एक है। इस लेख में, मैं दिखाऊंगा कि कैसे PHP भाषा और लार्वेल ढांचे के उदाहरण का उपयोग करके इस सिद्धांत को लागू किया जाए।

अक्सर, एमवीसी विकास मॉडल का वर्णन करते समय, अनुचित रूप से बड़े कार्यों को नियंत्रक को सौंपा जाता है। पैरामीटर, व्यावसायिक तर्क, प्राधिकरण और प्रतिक्रिया प्राप्त करना।

बेशक, लेख और पुस्तकों में इसे एक उदाहरण के रूप में वर्णित किया गया है, लेकिन अक्सर कार्य परियोजनाओं में कार्रवाई के लिए कॉल के रूप में माना जाता है। इस तरह के दृष्टिकोण से अनिवार्य रूप से अनियंत्रित वर्ग विकास होगा और कोड समर्थन बहुत जटिल हो जाएगा।

साझा जिम्मेदारी का सिद्धांत


एक उदाहरण के लिए हम बल्कि मोटे तौर पर लेंगे, लेकिन अक्सर "मोटी" नियंत्रक के प्रकार से मिलते हैं।

class OrderController extends Controller
{
    public function create(Request $request)
    {
        $rules = [
            'product_id' => 'required|max:10',
            'count' => 'required|max:10',
        ];
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return response()->json($validator->errors(), 400);
        }

         //  
        $order = Order::create($request->all());

        //   

        //  sms    

        return response()->json($order, 201);
    }
}

इस उदाहरण में, यह देखा जा सकता है कि नियंत्रक "ऑर्डर देने" के बारे में बहुत अधिक जानता है, इसे खरीदार को सूचित करने और सामानों को जमा करने का काम भी सौंपा जाता है।

हम यह सुनिश्चित करने का प्रयास करेंगे कि नियंत्रक को केवल पूरी प्रक्रिया को नियंत्रित करना है और कोई व्यावसायिक तर्क नहीं है।

शुरू करने के लिए, हम एक अलग अनुरोध वर्ग में मापदंडों को मान्य करेंगे।

class OrderRequest extends Request
{
    public function rules(): array
    {
         return [
             'product_id' => 'required|max:10',
             'count' => 'required|max:10',
         ];    
    }
}

और सभी व्यावसायिक तर्क को ऑर्डरस् सेवा वर्ग में ले जाएं

public class OrderService
{
    public function create(array $params)
    {
        //  

        //  

        //     sms
        $sms = new RuSms($appId);

        //  ,    
        $sms->send($number, $text);
     }
}

सेवा कंटेनर का उपयोग करके हम नियंत्रक में अपनी सेवा लागू करेंगे

नतीजतन, हमारे पास "पतली" नियंत्रक है।

class OrderController extends Controller
{
    protected $service;
	
    public function __construct(OrderService $service)
    {
	$this->service = $service;	
    }

    public function create(OrderRequest $request)
    {
        $this->service->create($request->all());

        return response()->noContent(201);
    }
}

पहले से बेहतर है। सभी व्यावसायिक तर्क को सेवा में स्थानांतरित कर दिया गया है। नियंत्रक केवल ऑर्डररेंस और ऑर्डरसेवर कक्षाओं के बारे में जानता है - अपना काम करने के लिए आवश्यक जानकारी का न्यूनतम सेट।

लेकिन अब हमारी सेवा को भी रिफैक्टिंग की जरूरत है। एक अलग वर्ग में sms भेजने का तर्क निकालते हैं।

class SmsRu
{
    protected $appId;

    public function __constructor(string $appId)
    {
        $this->appId = $appId;
    }

    public function send($number, $text): void
    {
          //     
    }
}    

और कंस्ट्रक्टर के माध्यम से इसे लागू करें

class OrderService
{
    private $sms;

    public function __construct()
    {
	$this->sms = new SmsRu($appId);	
    }

    public function create(array $params): void
    {
          //  

          //  

          //  ,    
          $this->sms->send($nubmer, $text);
    }
}    

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

interface SmsSenderInterface
{
    public function send($number, $text): void;
}

class SmsServiceProvider implements ServiceProviderInterface
{
    public function register(): void
    {
        $this->app->singleton(SmsSenderInterface::class, function ($app) {
            return new SmsRu($params['app_id']);
        });
    }
}

अब सेवा को अनावश्यक विवरणों से भी मुक्त कर दिया गया है

class OrderService
{
    private $sms;

    public function __construct(SmsSenderInterface $sms)
    {
	$this->sms = $sms;	
    }

    public function create(): void
    {
          //  

          //  

          //  ,    
          $this->sms->send($nubmer, $text);
    }
}    

इवेंट ड्रिवन आर्किटेक्चर


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

class OrderObserver
{
    private $sms;

    public function __construct(SmsSenderInterface $sms)
    {
	$this->sms = $sms;	
    }

    /**
     * Handle the Order "created" event.
     */
    public function created(Order $order)
    {
        $this->sms->send($nubmer, $text);
    }

AppServiceProvider में OrderObserver रजिस्टर करने के लिए मत भूलना

निष्कर्ष


मैं समझता हूं कि मैं इस पोस्ट में बहुत ही सामान्य बातों का वर्णन कर रहा हूं, लेकिन मैं यह दिखाना चाहता था कि लारवेल ढांचे पर यह सिद्धांत कैसे लागू होता है।

एसपीआर सिद्धांत सबसे महत्वपूर्ण में से एक है और बाकी के लिए मार्ग प्रशस्त करता है। इसका उपयोग करना आवश्यक है, खासकर जब से लारवेल फ्रेमवर्क सभी आवश्यक उपकरण प्रदान करता है।

All Articles