এমভিসি (লারাভেল) যেখানে যুক্তি যুক্ত করতে হবে


136

যাক আমি যখনই কোনও CRUD অপারেশন করি বা একটি নির্দিষ্ট উপায়ে একটি সম্পর্ক পরিবর্তন করি তখনও আমি অন্য কিছু করতে চাই Let's উদাহরণস্বরূপ, যখনই কেউ পোস্ট প্রকাশ করে আমি বিশ্লেষণের জন্য কোনও টেবিলে কিছু সঞ্চয় করতে চাই। সম্ভবত সেরা উদাহরণ না হলেও সাধারণভাবে এই "গ্রুপযুক্ত" কার্যকারিতা অনেক রয়েছে।

সাধারণত আমি এই ধরণের যুক্তিটি নিয়ন্ত্রকদের মধ্যে রাখি। যতক্ষণ না আপনি প্রচুর জায়গায় এই কার্যকারিতাটি পুনরুত্পাদন করতে চান যতক্ষণ না এই সমস্তই খুব সুন্দর and যখন আপনি পার্টিয়ালগুলি পেতে শুরু করেন, একটি এপিআই তৈরি করে এবং ডামি সামগ্রী তৈরি করে তা জিনিসগুলি DRY রাখার ক্ষেত্রে একটি সমস্যা হয়ে দাঁড়ায়।

এটি পরিচালনা করতে আমি যেভাবে দেখেছি তা হ'ল ইভেন্টগুলি, সংগ্রহশালা, লাইব্রেরিগুলি এবং মডেলগুলিতে যুক্ত করা। এখানে প্রতিটি আমার বোঝার জন্য:

পরিষেবাগুলি: বেশিরভাগ লোকেরা সম্ভবত এই কোডটি রাখবেন। পরিষেবাদিগুলির সাথে আমার প্রধান সমস্যাটি হ'ল কখনও কখনও তাদের মধ্যে নির্দিষ্ট কার্যকারিতা খুঁজে পাওয়া শক্ত হয় এবং আমার মনে হয় তারা কখন ভ্রষ্টর ব্যবহারে মনোযোগী হয় সে সম্পর্কে তারা ভুলে যায়। আমি কীভাবে জানতে পারি যে publishPost()যখন আমি ঠিক করতে পারি তখন আমাকে লাইব্রেরিতে কোনও পদ্ধতি কল করতে হবে $post->is_published = 1?

কেবলমাত্র শর্তটিই আমি এই কাজটি ভালভাবে দেখছি তা হল যদি আপনি কেবল পরিষেবাগুলি ব্যবহার করেন (এবং আদর্শিকভাবে নিয়ন্ত্রণকারীদের কাছ থেকে কোনও উপায়ে কোনওভাবেই অ্যাক্সেসযোগ্যকে অ্যাক্সেসযোগ্য করে তুলেন)।

শেষ পর্যন্ত মনে হচ্ছে এটি যদি আপনার অনুরোধগুলি সাধারণত আপনার মডেল কাঠামো অনুসরণ করে তবে অতিরিক্ত অযৌক্তিক ফাইলগুলির একগুচ্ছ তৈরি করবে।

ভান্ডারগুলি: আমি যা বুঝতে পারি তা থেকে এটি মূলত একটি সেবার মতো তবে একটি ইন্টারফেস রয়েছে যাতে আপনি ওআরএম এর মধ্যে স্যুইচ করতে পারেন, যা আমার দরকার নেই।

ইভেন্টগুলি: আমি এটিকে এক অর্থে সবচেয়ে মার্জিত সিস্টেম হিসাবে দেখছি কারণ আপনি জানেন যে আপনার মডেল ইভেন্টগুলি সর্বদা স্বতঃস্ফূর্ত পদ্ধতিতে ডাকা হয়, যাতে আপনি নিজের নিয়ন্ত্রককে সাধারণত লিখতে পারেন। আমি দেখতে পাচ্ছি যদিও এগুলি অগোছালো হয়ে উঠছে এবং কারও কাছে যদি সমালোচনামূলক সংযোগের জন্য ইভেন্টগুলি ব্যবহার করে বড় প্রকল্পের উদাহরণ থাকে তবে আমি এটি দেখতে চাই।

মডেল: প্রথাগতভাবে আমার কাছে এমন ক্লাস থাকত যেগুলি CRUD সম্পাদন করেছিল এবং সমালোচনামূলক সংযোগ পরিচালনা করেছিল। এটি আসলে জিনিসগুলিকে সহজ করে দিয়েছে কারণ আপনি CRUD এর চারপাশে সমস্ত কার্যকারিতা জানতেন + এটির সাথে যা কিছু করা উচিত ছিল।

সরল, তবে এমভিসি আর্কিটেকচারে এটি সাধারণত আমি যা দেখি তা হয় না। এক অর্থে যদিও আমি এটি পরিষেবাগুলির চেয়ে বেশি পছন্দ করি যেহেতু এটি সন্ধান করা কিছুটা সহজ, এবং ট্র্যাক রাখতে খুব কম ফাইল রয়েছে। এটি যদিও কিছুটা বিশৃঙ্খল হয়ে উঠতে পারে। আমি এই পদ্ধতির পতনগুলি শুনতে চাই এবং কেন বেশিরভাগ লোকেরা এটি করে বলে মনে হয় না।

প্রতিটি পদ্ধতির সুবিধা / অসুবিধাগুলি কী কী? আমি কিছু অনুপস্থিত করছি?


3
আপনি কি আপনার প্রশ্নকে ছোট করতে পারবেন?
আলফা

3
এছাড়াও আপনি এটি পরীক্ষা করতে পারেন ।
আলফা

1
"আমি কীভাবে জানতে পারি যে যখন আমি কেবল $ post-> is_pubmitted = 1 করতে পারি তখন আমাকে একটি লাইব্রেরিতে একটি পদ্ধতিতে প্রকাশিত পোস্ট () কল করতে হবে?" নথিপত্র?
সেজেজোজ

সুস্পষ্ট এবং ওআরএমএস সম্পর্কে অন্যতম সুন্দরী কি তাদের সাথে প্রচুর দস্তাবেজ ছাড়া কাজ করা সহজ?
সাব্রিনা লেগেট

1
এই পোস্ট করার জন্য ধন্যবাদ। আমি একই সমস্যাগুলির সাথে লড়াই করছি এবং আপনার পোস্ট এবং উত্তরটি অবিশ্বাস্যভাবে সহায়ক বলে খুঁজে পেয়েছি। শেষ পর্যন্ত আমি স্থির করেছি যে লারাভেল দ্রুত এবং নোংরা রুবি-অন-রেলস ওয়েবসাইটের বাইরে প্রসারিত যে কোনও কিছুর জন্য একটি ভাল আর্কিটেকচার সরবরাহ করে না। সর্বত্র ট্রেটস, ক্লাস ফাংশনগুলি খুঁজে পাওয়া এবং সর্বত্র অজস্র অটো-ম্যাজিক আবর্জনা খুঁজে পেতে অসুবিধা। ওআরএম কখনও কাজ করেনি এবং আপনি যদি এটি ব্যবহার করেন তবে আপনার সম্ভবত নোএসকিউএল ব্যবহার করা উচিত।
অ্যালেক্স বার্কার

উত্তর:


171

আমি মনে করি যে আপনি যে সমস্ত নিদর্শন / আর্কিটেকচার উপস্থাপন করেছেন ততক্ষণ আপনি সলাইড নীতি অনুসরণ করেন যতক্ষণ না ।

জন্য যেখানে লজিক যোগ করার জন্য আমি মনে করি যে এটির উল্লেখ করা জরুরী একক দায়িত্ব নীতি । এছাড়াও, আমার উত্তর বিবেচনা করে যে আপনি কোনও মাঝারি / বড় প্রকল্পে কাজ করছেন। যদি এটি কোনও পৃষ্ঠার কোনও থ্রো- প্রোজেক্ট হয় তবে এই উত্তরটি ভুলে যান এবং এটি সমস্ত কিছু নিয়ামক বা মডেলগুলিতে যুক্ত করুন।

সংক্ষিপ্ত উত্তরটি হ'ল: এটি আপনার কাছে (পরিষেবাগুলির সাথে) কী বোঝায়

দীর্ঘ উত্তর:

কন্ট্রোলার : কন্ট্রোলারদের দায়িত্ব কী? অবশ্যই, আপনি আপনার সমস্ত যুক্তি একটি নিয়ামকের মধ্যে রাখতে পারেন, তবে এটি কি নিয়ামকের দায়িত্ব? আমি তাই মনে করি না.

আমার জন্য, নিয়ামককে অবশ্যই একটি অনুরোধ এবং ডেটা ফেরত নিতে হবে এবং এটি বৈধতা, কল ডিবি পদ্ধতি ইত্যাদি কল করার জায়গা নয় ..

মডেল : কোনও ব্যবহারকারী যখন কোনও পোস্টের ভোট গণনা নিবন্ধন করে বা আপডেট করেন তখন স্বাগত ইমেল প্রেরণের মতো যুক্তি যুক্ত করার জন্য এটি কি ভাল জায়গা? আপনার কোডের অন্য কোনও জায়গা থেকে যদি একই ইমেলটি প্রেরণের দরকার হয় তবে কী হবে? আপনি একটি স্থির পদ্ধতি তৈরি করেন? যদি সেই ইমেলগুলিকে অন্য কোনও মডেল থেকে তথ্য প্রয়োজন হয়?

আমি মনে করি মডেলটির কোনও সত্তার প্রতিনিধিত্ব করা উচিত। Laravel, আমি শুধুমাত্র ভালো জিনিস যোগ করার জন্য মডেল বর্গ ব্যবহার fillable, guarded, tableএবং সম্পর্ক (এই কারণ আমি সংগ্রহস্থলের প্রয়োগ প্যাটার্ন ব্যবহার, অন্যথায় মডেল হবে save, update, find, ইত্যাদি পদ্ধতি)।

সংগ্রহশালা (সংগ্রহশালা প্যাটার্ন) : শুরুতে আমি এটি দেখে খুব বিভ্রান্ত হয়েছিলাম। এবং, আপনার মত, আমি ভেবেছিলাম "ভাল, আমি মাইএসকিউএল এবং এটি ব্যবহার করি" "

যাইহোক, আমি সংগ্রহস্থল প্যাটার্নটি ব্যবহারের পক্ষে বনাম কনস এর ভারসাম্য রক্ষা করেছি এবং এখন আমি এটি ব্যবহার করছি। আমি মনে করি এখন এই মুহুর্তে আমার কেবল মাইএসকিউএল ব্যবহার করা দরকার। তবে, এখন থেকে তিন বছর হলে আমাকে মোংগোডিবি-র মতো কিছুতে পরিবর্তন করা দরকার বেশিরভাগ কাজ। একটি অতিরিক্ত ইন্টারফেস এবং এ $app->bind(«interface», «repository»)

ইভেন্টস ( পর্যবেক্ষক প্যাটার্ন ): ইভেন্টগুলি যে কোনও শ্রেণিতে যে কোনও সময় নিক্ষিপ্ত হতে পারে এমনগুলির জন্য দরকারী। উদাহরণস্বরূপ, কোনও ব্যবহারকারীর জন্য বিজ্ঞপ্তি প্রেরণের বিষয়ে চিন্তা করুন। আপনার যখন প্রয়োজন হয়, আপনি আপনার অ্যাপ্লিকেশনটির যে কোনও ক্লাসে একটি বিজ্ঞপ্তি প্রেরণের জন্য ইভেন্টটি ফায়ার করেন। তারপরে, আপনার মতো ক্লাস থাকতে পারে UserNotificationEventsযাতে ব্যবহারকারী বিজ্ঞপ্তিগুলির জন্য আপনার বহিষ্কার করা সমস্ত ইভেন্ট পরিচালনা করে।

পরিষেবাদি : এখন অবধি, আপনার কাছে কন্ট্রোলার বা মডেলগুলিতে যুক্তি যুক্ত করার পছন্দ রয়েছে। আমার জন্য, পরিষেবাগুলির মধ্যে যুক্তি যুক্ত করা সমস্ত অর্থবোধ করে । আসুন এটির মুখোমুখি হোন, পরিষেবাদি ক্লাসগুলির অভিনব নাম। আপনার আবেদন হিসাবে এটি আপনার কাছে বোধগম্য এবং আপনি যতগুলি ক্লাস করতে পারেন।

এই উদাহরণটি ধরুন: কিছুক্ষণ আগে, আমি গুগল ফর্মগুলির মতো কিছু বিকাশ করেছি। আমি একটি দিয়ে শুরু CustomFormServiceএবং সঙ্গে শেষ পর্যন্ত CustomFormService, CustomFormRender, CustomFieldService, CustomFieldRender, CustomAnswerServiceএবং CustomAnswerRender। কেন? কারণ এটি আমার কাছে বোধগম্য হয়েছিল। আপনি যদি কোনও দলের সাথে কাজ করেন তবে আপনার যুক্তিটি যেখানে এটি দলের পক্ষে বোধগম্য হওয়া উচিত should

পরিষেবাদি বনাম কন্ট্রোলার / মডেলগুলি ব্যবহার করার সুবিধাটি হ'ল আপনি কোনও একক নিয়ামক বা একক মডেল দ্বারা সীমাবদ্ধ নন। আপনি আপনার অ্যাপ্লিকেশনটির নকশা এবং প্রয়োজনের উপর ভিত্তি করে প্রয়োজনীয় অনেকগুলি পরিষেবা তৈরি করতে পারেন। আপনার আবেদনের যে কোনও শ্রেণীর মধ্যে একটি পরিষেবা কল করার সুবিধা এতে যুক্ত করুন।

এটি দীর্ঘতর হয়, তবে আমি আপনাকে কীভাবে আমার অ্যাপ্লিকেশনটি কাঠামোবদ্ধ করে তুলে ধরতে চাই:

app/
    controllers/
    MyCompany/
        Composers/
        Exceptions/
        Models/
        Observers/
        Sanitizers/
        ServiceProviders/
        Services/
        Validators/
    views
    (...)

আমি প্রতিটি ফোল্ডার নির্দিষ্ট ফাংশনের জন্য ব্যবহার করি। উদাহরণস্বরূপ Validatorsডিরেক্টরিটিতে BaseValidatorবৈধতা যাচাইকরণের জন্য নির্দিষ্ট শ্রেণিবদ্ধ $rulesএবং $messagesনির্দিষ্ট ভ্যালিডেটরগুলির (সাধারণত প্রতিটি মডেলের জন্য একটি) দায়ী থাকে contains আমি সহজেই কোনও কোডের মধ্যে এই কোডটি রাখতে পারি, তবে এটি কেবলমাত্র পরিষেবার মধ্যে ব্যবহার করা হলেও (এখনই) এটির জন্য একটি নির্দিষ্ট ফোল্ডার রাখার বিষয়টি আমার কাছে বোধগম্য।

আমি আপনাকে নীচের নিবন্ধগুলি পড়ার পরামর্শ দিচ্ছি, কারণ তারা আপনাকে কিছুটা ভাল ব্যাখ্যা করতে পারে:

ডেইল রেস (কোডব্রাইটের লেখক) দ্বারা ছাঁচটি ভাঙ্গা: এটি আমার প্রয়োজন অনুসারে কয়েকটি জিনিস পরিবর্তন করে সত্ত্বেও আমি এটি সমস্ত একসাথে রেখেছি।

ক্রিস গুজির দ্বারা সংগ্রহস্থল এবং পরিষেবাদি ব্যবহার করে লারাভেলে আপনার কোড ডিকোপলিং: এই পোস্টটি একটি পরিষেবা এবং সংগ্রহস্থল নিদর্শন কী এবং কীভাবে তারা একসাথে ফিট হয় তা ভাল করে ব্যাখ্যা করে।

ল্যারাকাস্টগুলির সরলীকৃতএকক দায়িত্বও রয়েছে যা ব্যবহারিক উদাহরণ সহ ভাল সংস্থান (যদিও আপনাকে অর্থ দিতে হবে)।


3
দুর্দান্ত ব্যাখ্যা। এই মুহুর্তে আমি যেখানে দাঁড়িয়ে আছি তা এখানে - বর্তমান প্রকল্পে আমি আমার ব্যবসায়িক যুক্তিগুলিকে মডেলগুলিতে রাখছি এবং এটি আসলে খুব ভালভাবে কাজ করছে। আমাদের অবশ্যই সলিডকে কিছুটা চাপিয়ে দেওয়া দরকার, তবে এটি এখনও আমাদের সমস্যার মধ্যে ফেলেনি। এটি দ্রুত, এটি দারুণ নোংরা, তবে এখনও আমাদের প্রকল্পটি খুব রক্ষণাবেক্ষণযোগ্য কারণ এটি এতটাই শুষ্ক। আমি এই মুহুর্তে তাদের সাথে লেগে থাকার সাথে অবশ্যই ঠিক আছি কারণ তারা কাজটি সম্পন্ন করে, তবে ভবিষ্যতের যে কোনও প্রকল্পে আমি সম্ভবত যা কিছু মানদণ্ডের সাথে যাব, যা মনে হয় এটি সংগ্রহস্থল হয়ে গেছে।
সাব্রিনা লেগেট

2
আমি খুশি যে আপনি এমন একটি উপায় খুঁজে পেয়েছেন যা আপনার বোঝার জন্য। আপনি আজ যে অনুমানগুলি করেন তা নিয়ে কেবল সাবধান হন । আমি 3+ বছর ধরে একটি প্রকল্পে কাজ করেছি এবং 5000+ লাইন কোডের কন্ট্রোলার এবং মডেলগুলি দিয়ে শেষ করেছি। আপনার প্রকল্পের সাথে সৌভাগ্য কামনা করছি।
Luís ক্রুজ

এছাড়াও নোংরা কিন্ত আমি মডেলগুলি বিশাল আকার এড়ানোর জন্য বৈশিষ্ট্যগুলি ব্যবহার করার বিষয়ে ভাবছিলাম। সেভাবে আমি তাদের কিছুটা আলাদা করতে পারি
সাব্রিনা লেগেট

এই নিবন্ধটি পরিষেবাগুলি ব্যবহার করার জন্য যখন বোধগম্য হয় তখন তা ভালভাবে যুক্ত হয়। আপনার ফর্মের উদাহরণে পরিষেবাগুলি ব্যবহার করা বোধগম্য হয় তবে তিনি কীভাবে এটি করেন তা তিনি ব্যাখ্যা করেন, যখন যুক্তিটি কোনও মডেলের সাথে সরাসরি সম্পর্কিত হয় যখন তিনি সেই মডেলটিতে রাখেন। justinweiss.com/articles/where-do-you-put-your-code
লেগেট

আমি সত্যিই ব্যাখ্যা পছন্দ। আমার একটি প্রশ্ন আছে: আপনি নিয়ামকটিতে বৈধতা না দেওয়ার কথা উল্লেখ করেছেন, তাই আপনি বৈধতা দেওয়ার সেরা জায়গাটি কোথায় বলে মনে করেন? অনেকে এটিকে বর্ধিত অনুরোধের ক্লাসে রাখার পরামর্শ দেয় (এবং আমরা বর্তমানে যা করি তাও) তবে আমি যদি কেবলমাত্র http অনুরোধে বৈধতা না চাই, তবে কারিগর কমান্ড ইত্যাদিতেও কি এটি সত্যিই একটি ভাল জায়গা?
কিংশার্ক

24

আমি আমার নিজের প্রশ্নের জবাব পোস্ট করতে চেয়েছিলাম। আমি বেশ কয়েকদিন ধরে এ সম্পর্কে কথা বলতে পারি, তবে আমি এটি পেতে তা নিশ্চিত করার জন্য এই পোস্টটি দ্রুত পাওয়ার চেষ্টা করব।

লারাভেল সরবরাহ করে এমন বিদ্যমান কাঠামোটি ব্যবহার করে আমি শেষ করেছি, যার অর্থ আমি আমার ফাইলগুলি প্রাথমিকভাবে মডেল, ভিউ এবং কন্ট্রোলার হিসাবে রেখেছি। আমার কাছে পুনরায় ব্যবহারযোগ্য উপাদানগুলির জন্য একটি লাইব্রেরি ফোল্ডার রয়েছে যা সত্যিকারের মডেল নয়।

আমি আমার মডেলগুলিকে পরিষেবা / লাইব্রেরিতে আবদ্ধ করিনি । প্রদত্ত সমস্ত কারণে 100% পরিষেবা ব্যবহারের সুবিধা সম্পর্কে আমাকে রাজি করায় না। যদিও আমি ভুল হতে পারি, যতক্ষণ না আমি দেখতে পাচ্ছি তারা কেবলমাত্র মডেলগুলির সাথে কাজ করার সময় আমার কাছে তৈরি করতে এবং স্যুইচ করতে হবে এমন অতিরিক্ত প্রায় খালি ফাইলগুলির টনগুলির ফলস্বরূপ এবং সত্যই স্পষ্টভাবে ব্যবহারের সুবিধা হ্রাস করতে পারে (বিশেষত যখন এটি পুনরায় মডেলগুলির ক্ষেত্রে আসে) উদাহরণস্বরূপ, পৃষ্ঠা-রচনা, স্কোপস ইত্যাদি ব্যবহার করে)।

আমি মডেলগুলিতে ব্যবসায়ের যুক্তি রেখেছি এবং সরাসরি আমার নিয়ামকগণের কাছ থেকে স্পষ্টত অ্যাক্সেস করি। ব্যবসায়ের যুক্তি বাইপাস না হয়ে যায় তা নিশ্চিত করার জন্য আমি অনেকগুলি পন্থা ব্যবহার করি:

  • অ্যাকসেসর এবং মিউটর: লারাভেলের দুর্দান্ত অ্যাকসেসর এবং মিউটর রয়েছে। আমি যখনই কোনও পদক্ষেপটি খসড়া থেকে প্রকাশিত স্থানান্তরিত করতে চাইলে আমি কোনও ক্রিয়া সম্পাদন করতে চাই তবে আমি ফাংশন সেটসপ্রকাশিতঅ্যাট্রিবিউট তৈরি করে এবং সেখানে যুক্তি সহ এটি কল করতে পারি
  • ওভাররাইডিং তৈরি / আপডেট ইত্যাদি: আপনি নিজের মডেলগুলিতে স্বতন্ত্র পদ্ধতিগুলি কাস্টম কার্যকারিতা অন্তর্ভুক্ত করতে সর্বদা ওভাররাইড করতে পারেন। যে কোনও সিআরইউডি অপারেশনে আপনি কার্যকারিতা কল করতে পারেন। সম্পাদনা: আমি মনে করি নতুন লারাভেল সংস্করণগুলিতে ওভাররাইড তৈরির সাথে একটি বাগ রয়েছে (তাই আমি এখন বুটে নিবন্ধিত ইভেন্টগুলি ব্যবহার করি)
  • বৈধতা: আমি আমার বৈধতা একইভাবে হুক করেছি, উদাহরণস্বরূপ, আমি সিআরইউডি ফাংশন ও প্রয়োজন অনুসারে অ্যাকসেসর / মিউটরগুলিকে ওভাররাইড করে যাচাইকরণ চালাব। আরও তথ্যের জন্য এসেনসি বা ডুইটওয়টসন / বৈধকরণ দেখুন।
  • যাদু পদ্ধতি: আমি উপযুক্ত যেখানে কার্যকারিতা হুক করতে আমার মডেলগুলির __get এবং __set পদ্ধতি ব্যবহার করি
  • স্পষ্টত প্রসারিত: আপনি যদি সমস্ত আপডেট / তৈরি করতে চান এমন কোনও ক্রিয়া থাকে তবে আপনি এমনকি বুদ্ধিমান প্রসারিত করতে পারেন এবং একাধিক মডেলে এটি প্রয়োগ করতে পারেন।
  • ইভেন্টস: এটি একটি সোজা এগিয়ে এবং সাধারণভাবে এটি করার জন্য স্থানটিতে সম্মত। আমি মনে করি ইভেন্টগুলির সাথে সবচেয়ে বড় অপূর্ণতা ব্যতিক্রমগুলি সন্ধান করা শক্ত (লারাভেলের নতুন ইভেন্ট সিস্টেমের ক্ষেত্রে এটি নতুন ক্ষেত্রে নাও হতে পারে)। আমি আমার ইভেন্টগুলিকে যখন ডাকা হয় তার পরিবর্তে তারা যা করে তা গোষ্ঠীকরণ করতেও পছন্দ করি ... উদাহরণস্বরূপ, একটি মেলসেন্ডার গ্রাহক রয়েছে যা মেল পাঠায় এমন ইভেন্টগুলির জন্য শোনেন।
  • পিভট / বেলংস টোমেন ইভেন্টগুলি যুক্ত করা: একটি বিষয় যা আমি সবচেয়ে দীর্ঘস্থায়ী করেছিলাম তার মধ্যে একটি হল কীভাবে সম্পর্কযুক্ত সম্পর্কটি সংযুক্ত করার সাথে আচরণটি যুক্ত করা যায় o উদাহরণস্বরূপ, যখনই কোনও ব্যবহারকারী কোনও গোষ্ঠীতে যোগদান করে তখন একটি ক্রিয়া সম্পাদন করা। আমি প্রায় এটির জন্য একটি কাস্টম লাইব্রেরি পলিশিং সম্পন্ন করেছি। আমি এখনও এটি প্রকাশ করি নি তবে এটি কার্যকরী! শীঘ্রই একটি লিঙ্ক পোস্ট করার চেষ্টা করবে। সম্পাদনা করুন আমি আমার সমস্ত পাইভটকে সাধারণ মডেলগুলিতে পরিণত করেছি এবং আমার জীবন এত সহজ হয়েছে ...

মডেলগুলি ব্যবহার করে মানুষের উদ্বেগের সমাধান:

  • সংগঠন: হ্যাঁ আপনি যদি মডেলগুলিতে আরও যুক্তি যুক্ত করেন তবে সেগুলি আরও দীর্ঘ হতে পারে তবে সাধারণভাবে আমি পেয়েছি আমার models৫% মডেল এখনও খুব ছোট। যদি আমি বৃহত্তরগুলি সংগঠিত করতে পছন্দ করি তবে বৈশিষ্ট্যগুলি ব্যবহার করে এটি করতে পারি (উদাহরণস্বরূপ, মডেলটির জন্য আরও কিছু ফাইল যেমন পোস্টস্কোপস, পোস্টঅ্যাকসেসারস, পোস্টভিলেশন ইত্যাদি প্রয়োজন হিসাবে ফোল্ডার তৈরি করুন)। আমি জানি এটি অগত্যা কী কী বৈশিষ্ট্যের জন্য তা নয় তবে এই সিস্টেমটি সমস্যা ছাড়াই কাজ করে।

অতিরিক্ত দ্রষ্টব্য: আমি আপনার মডেলগুলিকে পরিষেবাগুলিতে মুড়িয়ে ফেলার মতো মনে করি একটি সুইস আর্মি ছুরি, প্রচুর সরঞ্জাম সহ এবং এটির চারপাশে আরেকটি ছুরি তৈরি করা যা মূলত একই জিনিসটি করে? হ্যাঁ, কখনও কখনও আপনি একটি ফলকটি টেপ করতে বা দুটি ব্লেড একসাথে ব্যবহার করা নিশ্চিত করতে পারেন ... তবে এটি করার অন্যান্য উপায় রয়েছে ...

যখন পরিষেবাগুলি ব্যবহার করবেন : কখন এই পরিষেবাগুলি ব্যবহার করবেন সে সম্পর্কে এই নিবন্ধটি খুব ভাল উদাহরণ দেয় ( ইঙ্গিত: এটি প্রায়শই হয় না )। তিনি বলেন মূলত যখন আপনার অবজেক্টগুলি তার জীবনচক্রের অদ্ভুত অংশগুলিতে একাধিক মডেল বা মডেল ব্যবহার করে তখন তা বোঝা যায়। http://www.justinweiss.com/articles/where-do-you-put-your-code/


2
আকর্ষণীয় এবং কার্যকর ধারণা। তবে আমি কৌতূহলী - আপনি যদি আপনার ব্যবসায়িক যুক্তিকে ইউনিট-টেস্ট করেন তবে এটি যদি এমন মডেলগুলির সাথে আবদ্ধ থাকে যা ডাটাবেসের সাথে আবদ্ধ থাকে?
জাস্টামার্টিন

code.tutsplus.com/tutorials/... অথবা আপনি ঘটনা মত আমি বললাম আপনি আরও এটা ভেঙ্গে করতে চান তাহলে ব্যবহার করতে পারেন
সাবরিনা Leggett

1
@ জুস্টামার্টিন আপনি কি নিশ্চিত যে আপনি কেবল আপনার ইউনিট পরীক্ষায় ডাটাবেস ব্যবহার করতে পারবেন না? এটি না করার কারণ কী? অনেক লোক সম্মত হন যে প্রায়শই ইউনিট পরীক্ষায় ডাটাবেস ব্যবহার করা ঠিক হয়। (মার্টিন ফওলর , মার্টিনফাউলার / বিলিকি / ইউনাইটেস্টেস্ট এইচটিএমএল সহ : "আমি বাহ্যিক সংস্থার জন্য ডাবল ব্যবহারকে নিরঙ্কুশ নিয়ম হিসাবে বিবেচনা করি না। যদি সংস্থানটির সাথে কথা বলা আপনার পক্ষে স্থিতিশীল এবং দ্রুত হয় তবে তা না করার কোনও কারণ নেই) এটি আপনার ইউনিট পরীক্ষায় রয়েছে ")
অ্যালেক্স পি।

@ AlexP11223 হ্যাঁ, এটি উপলব্ধি করে। আমি এসকিউএলাইটকে আমার পরীক্ষার ডেটাবেস হিসাবে একীভূত করার চেষ্টা করেছি এবং সাধারণভাবে এটি ঠিক হয়ে গেছে, যদিও এসকিউএলাইটের কিছু গুরুতর সীমাবদ্ধতা রয়েছে যার জন্য লারাভেল মাইগ্রেশন এবং কাস্টম ক্যোয়ারিতে (যদি থাকে) ounted অবশ্যই, তারপরে সেগুলি কঠোরভাবে ইউনিট টেস্ট নয় বরং কার্যকরী পরীক্ষা নয়, তবে এটি আরও কার্যকর। তবুও, আপনি যদি নিজের মডেলটিকে সম্পূর্ণ বিচ্ছিন্নভাবে পরীক্ষা করতে চান (কঠোর ইউনিট পরীক্ষা হিসাবে), এটির জন্য অতিরিক্ত কোড (মক ইত্যাদি) লক্ষণীয় পরিমাণের প্রয়োজন হতে পারে।
জাস্টামার্টিন

22

কন্ট্রোলার এবং মডেলগুলির মধ্যে যুক্তি তৈরি করতে আমি যা ব্যবহার করি তা হ'ল একটি পরিষেবা স্তর তৈরি করা । মূলত, আমার অ্যাপ্লিকেশনটিতে যে কোনও ক্রিয়াকলাপের জন্য এটি আমার প্রবাহ:

  1. নিয়ামক ব্যবহারকারীর অনুরোধিত ক্রিয়া পান এবং প্যারামিটারগুলি প্রেরণ করেন এবং সমস্ত কিছু একটি পরিষেবা শ্রেণিতে অর্পণ করেন।
  2. পরিষেবা শ্রেণি অপারেশন সম্পর্কিত সমস্ত যুক্তিগুলি করে: ইনপুট বৈধকরণ, ইভেন্ট লগিং, ডাটাবেস ক্রিয়াকলাপ ইত্যাদি ...
  3. মডেল ক্ষেত্রগুলির তথ্য, ডেটা ট্রান্সফর্মেশন এবং বৈশিষ্ট্যগুলির বৈধতাগুলির সংজ্ঞা রাখে।

আমি এটি এইভাবে করি:

কোনও কিছু তৈরি করার জন্য এটি একটি নিয়ামকের পদ্ধতি:

public function processCreateCongregation()
{
    // Get input data.
    $congregation                 = new Congregation;
    $congregation->name           = Input::get('name');
    $congregation->address        = Input::get('address');
    $congregation->pm_day_of_week = Input::get('pm_day_of_week');
    $pmHours                      = Input::get('pm_datetime_hours');
    $pmMinutes                    = Input::get('pm_datetime_minutes');
    $congregation->pm_datetime    = Carbon::createFromTime($pmHours, $pmMinutes, 0);

    // Delegates actual operation to service.
    try
    {
        CongregationService::createCongregation($congregation);
        $this->success(trans('messages.congregationCreated'));
        return Redirect::route('congregations.list');
    }
    catch (ValidationException $e)
    {
        // Catch validation errors thrown by service operation.
        return Redirect::route('congregations.create')
            ->withInput(Input::all())
            ->withErrors($e->getValidator());
    }
    catch (Exception $e)
    {
        // Catch any unexpected exception.
        return $this->unexpected($e);
    }
}

এটি সার্ভিস ক্লাস যা অপারেশন সম্পর্কিত যুক্তিটি করে:

public static function createCongregation(Congregation $congregation)
{
    // Log the operation.
    Log::info('Create congregation.', compact('congregation'));

    // Validate data.
    $validator = $congregation->getValidator();

    if ($validator->fails())
    {
        throw new ValidationException($validator);
    }

    // Save to the database.
    $congregation->created_by = Auth::user()->id;
    $congregation->updated_by = Auth::user()->id;

    $congregation->save();
}

এবং এটি আমার মডেল:

class Congregation extends Eloquent
{
    protected $table = 'congregations';

    public function getValidator()
    {
        $data = array(
            'name' => $this->name,
            'address' => $this->address,
            'pm_day_of_week' => $this->pm_day_of_week,
            'pm_datetime' => $this->pm_datetime,
        );

        $rules = array(
            'name' => ['required', 'unique:congregations'],
            'address' => ['required'],
            'pm_day_of_week' => ['required', 'integer', 'between:0,6'],
            'pm_datetime' => ['required', 'regex:/([01]?[0-9]|2[0-3]):[0-5]?[0-9]:[0-5][0-9]/'],
        );

        return Validator::make($data, $rules);
    }

    public function getDates()
    {
        return array_merge_recursive(parent::getDates(), array(
            'pm_datetime',
            'cbs_datetime',
        ));
    }
}

লারাভেল অ্যাপ্লিকেশনটির জন্য আমার কোডটি সংগঠিত করতে এইভাবে ব্যবহার করার জন্য আরও তথ্যের জন্য: https://github.com/rmariuzzo/ পিটিমি


দেখে মনে হচ্ছে পরিষেবাগুলি সেগুলিকেই আমি আমার পোস্টে গ্রন্থাগার হিসাবে উল্লেখ করেছি। আমি মনে করি আপনার যদি একাধিক ওআরএমএস ব্যবহার করার প্রয়োজন না হয় তবে এটি সংগ্রহস্থলের চেয়ে ভাল but এটি কিনে মডেল স্ট্রাকচারটি আয়না করে শেষ হয়েছে যাতে আপনি এই সমস্ত অতিরিক্ত ফাইল পেয়েছেন। কেন এটি কেবল মডেলগুলিতে অন্তর্ভুক্ত করবেন না? কমপক্ষে সেই পদ্ধতিতে আপনার কাছে অতিরিক্ত ফাইল নেই।
সাব্রিনা লেগেট

@ সাব্রিনা জেলবার্ট এটি একটি আকর্ষণীয় প্রশ্ন, আমাকে মডেলদের ডাটাবেস সত্তাকে উপস্থাপন করতে এবং কোনও যুক্তি না রাখতে শেখানো হয়েছে। সমস্ত যুক্তি এবং কোনও অতিরিক্ত ক্রিয়াকলাপ ধরে রাখার জন্য আমি পরিষেবাগুলির নামে এই অতিরিক্ত ফাইলগুলি তৈরি করেছিলাম। আপনি পূর্বে বর্ণিত ইভেন্টগুলির পুরো অর্থটি কী তা আমি নিশ্চিত নই, তবে আমি মনে করি পরিষেবাগুলির সাথে এবং লারাভেলের ইভেন্টগুলি ব্যবহার করে আমরা সমস্ত পরিষেবা পদ্ধতি শুরু এবং শেষের দিকে ঘটনাগুলিকে আগুনে চালিয়ে দিতে পারি। এইভাবে কোনও ঘটনা সম্পূর্ণ যুক্তি থেকে ডিকপল করা যেতে পারে। আপনি কি মনে করেন?
রুবেন্স মারিজুজ্জো

আমাকে মডেল সম্পর্কেও শেখানো হয়েছিল ... কেন (সম্ভবত নির্ভরতার বিষয়গুলি) এর জন্য একটি ভাল ব্যাখ্যা পেয়ে ভাল লাগবে?
সাব্রিনা লেগেট

আমি এই পদ্ধতির পছন্দ! মডেলটির যুক্তিগুলি কীভাবে পরিচালনা করা উচিত সে সম্পর্কে ধারণা পেতে আমি ইন্টারনেট অনুসন্ধান করছি, রিপোজিটরিগুলি দেখেছি তবে এটি কিছুটা ব্যবহারের জন্য খুব জটিল এবং অকেজো বলে মনে হয়েছে। পরিষেবাদিগুলি একটি ভাল ধারণা। অ্যাপ্লিকেশন ফোল্ডারে পরিষেবাদির ফোল্ডার তৈরি করার পরে আমার প্রশ্নটি হ'ল, আপনার বুট স্ট্র্যাপ / স্টার্ট.এফপি বা বুট করার জন্য কোথাও অন্তর্ভুক্ত করতে হবে কারণ আমি আপনার গিটটি খুঁজে পাচ্ছিলাম না? @RubensMariuzzo। এটি অ্যাপ্লিকেশন সহ স্বয়ংক্রিয়ভাবে উপলব্ধ হয়? সুতরাং আমরা কেবল ক্রেগ্রিগেশন সার্ভিস :: getCongregations () ব্যবহার করতে পারি; ??
ওগুজহান

1
আপনি যদি যা করছেন সব কিছু যদি হয় $congregation->save();তবে সম্ভবত আপনার रिपোজিটরিগুলির প্রয়োজন হবে না। তবে, আপনি দেখতে পাচ্ছেন যে আপনার ডেটা অ্যাক্সেসের প্রয়োজন সময়ের সাথে সাথে বৃদ্ধি increase আপনার জন্য চাহিদা আছে শুরু হতে পারে $congregation->destroyByUser()বা $congregationUsers->findByName($arrayOfSelectedFields);ইত্যাদি। ডেটা অ্যাক্সেসের প্রয়োজনীয়তা থেকে আপনার পরিষেবাগুলি কেন দ্বি-দম্পতি নয়। আপনার বাকী অ্যাপ্লিকেশনগুলি / অ্যারেগুলি রেপোগুলি থেকে ফিরে আসার জন্য কাজ করতে দিন এবং ম্যানিপুলেটিং / ফর্ম্যাটিং / ইত্যাদি পরিচালনা করুন ... আপনার রেপো বৃদ্ধি পাবে (তবে এগুলিকে বিভিন্ন ফাইলে বিভক্ত করুন, শেষ পর্যন্ত কোনও প্রকল্পের জটিলতা কোথাও থাকতে হবে)।
অগ্রহামার

12

আমার মতে লারাভেলের কাছে ইতিমধ্যে আপনার ব্যবসায়ের যুক্তি সঞ্চয় করার জন্য অনেক বিকল্প রয়েছে।

সংক্ষিপ্ত উত্তর:

  • Requestআপনার ইনপুটটি স্বয়ংক্রিয়ভাবে বৈধ করতে ল্যারাভেলের অবজেক্টগুলি ব্যবহার করুন এবং তারপরে অনুরোধে ডেটা চালিয়ে যান (মডেল তৈরি করুন)। যেহেতু ব্যবহারকারীদের ইনপুট সব সরাসরি পাওয়া যায় অনুরোধ, আমি বিশ্বাস করি এটা জ্ঞান করে তোলে এই এখানে পারফর্ম করতে।
  • লারাভেলের Jobঅবজেক্টগুলি এমন কার্য সম্পাদন করতে ব্যবহার করুন যাতে স্বতন্ত্র উপাদানগুলির প্রয়োজন হয়, তবে কেবল সেগুলি প্রেরণ করুন। আমি মনে করি Jobএর পরিষেবা ক্লাসগুলি অন্তর্ভুক্ত। তারা কোনও কার্য সম্পাদন করে যেমন ব্যবসায়ের যুক্তি।

দীর্ঘ (এর) উত্তর:

প্রয়োজন হলে প্রতিক্রিয়াগুলি ব্যবহার করুন: সংগ্রহস্থলগুলি অত্যধিক চাপের জন্য আবদ্ধ থাকে এবং বেশিরভাগ সময় কেবল accessorমডেলটির জন্য সহজেই ব্যবহৃত হয় । আমি মনে করি তারা স্পষ্টভাবে কিছু ব্যবহার আছে, কিন্তু যদি না আপনি একটি বৃহদায়তন অ্যাপ্লিকেশন বিকাশ করছি প্রয়োজন নমনীয়তা যে পরিমাণ আপনি সম্পূর্ণরূপে খাদে Laravel পাবে জন্য, ভান্ডার থেকে দূরে থাকুন। আপনি পরে নিজেকে ধন্যবাদ জানাতে হবে এবং আপনার কোড আরও অনেক সোজা এগিয়ে হবে।

নিজেকে পিএইচপি ফ্রেমওয়ার্কগুলি পরিবর্তন করতে চলেছে বা ল্যারাভেল সমর্থন করে না এমন একটি ডেটাবেস টাইপের ক্ষেত্রে নিজেকে জিজ্ঞাসা করুন ।

যদি আপনার উত্তরটি "সম্ভবত না" হয়, তবে সংগ্রহস্থল প্যাটার্নটি প্রয়োগ করবেন না।

উপরের পাশাপাশি, দয়া করে সুস্পষ্ট ওআরএম এর মতো স্পর্শকাতর মতো কোনও প্যাটার্নটি চাপবেন না। আপনি কেবল এমন জটিলতা যুক্ত করছেন যা প্রয়োজনীয় নয় এবং এটি আপনার কোনও উপকারে আসবে না।

পরিষেবাগুলি অল্প পরিমাণে ব্যবহার করুন: আমার কাছে পরিষেবা ক্লাসগুলি, প্রদত্ত নির্ভরতা সহ একটি নির্দিষ্ট কাজ সম্পাদন করার জন্য ব্যবসার যুক্তি সঞ্চয় করার জায়গা are লারাভেলের এইগুলি "জবস" নামে বাক্সের বাইরে রয়েছে এবং তাদের কাস্টম সার্ভিস ক্লাসের চেয়ে অনেক বেশি নমনীয়তা রয়েছে।

লারাভেলের কাছে MVCলজিকের সমস্যার সমাধানের মতো সমাধান রয়েছে বলে আমি মনে করি । এটি কেবল একটি বিষয় বা সংস্থা।

উদাহরণ:

অনুরোধ :

namespace App\Http\Requests;

use App\Post;
use App\Jobs\PostNotifier;
use App\Events\PostWasCreated;
use App\Http\Requests\Request;

class PostRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title'       => 'required',
            'description' => 'required'
        ];
    }

    /**
     * Save the post.
     *
     * @param Post $post
     *
     * @return bool
     */
    public function persist(Post $post)
    {
        if (!$post->exists) {
            // If the post doesn't exist, we'll assign the
            // post as created by the current user.
            $post->user_id = auth()->id();
        }

        $post->title = $this->title;
        $post->description = $this->description;

        // Perform other tasks, maybe fire an event, dispatch a job.

        if ($post->save()) {
            // Maybe we'll fire an event here that we can catch somewhere else that
            // needs to know when a post was created.
            event(new PostWasCreated($post));

            // Maybe we'll notify some users of the new post as well.
            dispatch(new PostNotifier($post));

            return true;
        }

        return false;
    }
}

নিয়ামক :

namespace App\Http\Controllers;

use App\Post;
use App\Http\Requests\PostRequest;

class PostController extends Controller
{

   /**
    * Creates a new post.
    *
    * @return string
    */
    public function store(PostRequest $request)
    {
        if ($request->persist(new Post())) {
            flash()->success('Successfully created new post!');
        } else {
            flash()->error('There was an issue creating a post. Please try again.');
        }

        return redirect()->back();
    }

   /**
    * Updates a post.
    *
    * @return string
    */
    public function update(PostRequest $request, $id)
    {
        $post = Post::findOrFail($id);

        if ($request->persist($post)) {
            flash()->success('Successfully updated post!');
        } else {
            flash()->error('There was an issue updating this post. Please try again.');
        }

        return redirect()->back();
    }
}

উপরের উদাহরণে, অনুরোধ ইনপুটটি স্বয়ংক্রিয়ভাবে বৈধ হয়ে গেছে, এবং আমাদের যা করা দরকার তা হল স্থির পদ্ধতিটি কল করা এবং একটি নতুন পোস্টে পাস করা। আমি মনে করি পঠনযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতা সর্বদা জটিল এবং বিনা নকশার নকশার ধরণগুলিকে ট্রাম্প করা উচিত।

তারপরে আপনি পোস্টগুলি আপডেট করার জন্য একই একই অবিচলিত পদ্ধতিটিও ব্যবহার করতে পারেন, যেহেতু আমরা পোস্টটি ইতিমধ্যে বিদ্যমান কিনা তা পরীক্ষা করতে পারি এবং যখন প্রয়োজন হয় তখন বিকল্প যুক্তি সম্পাদন করতে পারি।


তবে - চাকরীগুলি কি সারিবদ্ধ হওয়ার কথা নয়? কখনও কখনও আমরা সম্ভবত এটি সারিবদ্ধ হতে চাই কিন্তু সবসময় না। পরিবর্তে আদেশ ব্যবহার করবেন না কেন? আপনি যদি এমন কিছু ব্যবসায়িক যুক্তি লিখতে চান যা একটি আদেশ বা একটি ইভেন্ট বা একটি সারিবদ্ধ হিসাবে কার্যকর করা যেতে পারে?
সাব্রিনা লেগেট

1
চাকরীর সারি করার দরকার নেই। ShouldQueueলারাভেল যে কাজটি সরবরাহ করে তার ইন্টারফেসটি প্রয়োগ করে আপনি তা উল্লেখ করেছেন । আপনি যদি কোনও আদেশ বা ইভেন্টে ব্যবসায়িক যুক্তি লিখতে চান তবে কেবল সেই ইভেন্ট / কমান্ডের মধ্যে কাজটি সরিয়ে দিন। ল্যারাভেলসের কাজগুলি অত্যন্ত নমনীয়, তবে শেষ পর্যন্ত তারা কেবল সরল পরিষেবা শ্রেণি।
স্টিভ বাউমান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.