এটি কি খারাপ অভ্যাস যা পরিষেবার পরিবর্তে কন্ট্রোলার কল সংগ্রহস্থলকে কল করে?


43

এটি কি খারাপ অভ্যাস যা পরিষেবার পরিবর্তে কন্ট্রোলার কল সংগ্রহস্থলকে কল করে?

আরও ব্যাখ্যা করতে:

আমি বুঝতে পারি যে ভাল ডিজাইনে নিয়ন্ত্রণকারীরা কল পরিষেবা এবং পরিষেবা ব্যবহারের সংগ্রহস্থল।

তবে কখনও কখনও নিয়ন্ত্রকের মধ্যে আমার কোনও যুক্তি / প্রয়োজন হয় না এবং কেবল ডিবি থেকে আনতে হয় এবং এটি দেখতে পাস করতে হয়।

এবং আমি কেবল সংগ্রহস্থল কল করে এটি করতে পারি - পরিষেবা কল করার প্রয়োজন নেই - এটি কি খারাপ অভ্যাস?


আপনি কীভাবে পরিষেবাটি কল করছেন? একটি REST ইন্টারফেস মাধ্যমে?
রবার্ট হার্ভে

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

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

4
এমন একটি কঠোর এবং দ্রুত নিয়ম নেই যে আপনার নিয়ামক -> পরিষেবাদি -> নিয়ন্ত্রণকারী -> সংগ্রহস্থলের উপরে সংগ্রহস্থল কাঠামো থাকা উচিত। সঠিক প্রয়োগের জন্য সঠিক প্যাটার্নটি চয়ন করুন। আমি যা বলব তা হ'ল আপনার আবেদনটি সামঞ্জস্য করা উচিত।
নিকোলাইড্যান্টে

হতে পারে আপনি একটি জেনেরিক পরিষেবা নিয়ে আসতে পারেন যা কেবল আপনার অনুরোধটি সংগ্রহস্থলের কাছে পাঠিয়ে দেয় এবং তারপরে ফিরে আসে returns এটি অভিন্ন ইন্টারফেস রাখতে দরকারী হতে পারে এবং যদি ভবিষ্যতে আপনার সংগ্রহস্থলের কল করার আগে কিছু করার জন্য একটি সত্যিকারের পরিষেবা যুক্ত করতে হয় তবে তা সহজ be
হেনরিক

উত্তর:


32

না, এটিকে এভাবে ভাবুন: একটি সংগ্রহস্থলটি একটি পরিষেবা (এছাড়াও)।

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

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

পড়ার দৃশ্যের জন্য এটি সাধারণ বিষয় হল এটি আপনাকে একটি ডিটিও / ভিউমোডেল হিসাবে প্রজেক্ট করার জন্য সত্ত্বার প্রয়োজন। এর মাঝে একটি পরিষেবা স্তর থাকার ফলে প্রায়শই প্রচুর পদ্ধতির মধ্য দিয়ে যায় যা কুরুচিপূর্ণ হয়।


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

আমি কেবল একটি পরিষেবার ব্যবহারকে ন্যায়সঙ্গত করার জন্য একটি বরং জটিল কোড লক্ষ্য করেছি। অ্যাবসার্ড, সর্বনিম্ন ...
Gi1ber7

সুতরাং আমার সংগ্রহস্থলটি 'ব্যবসায়িক অবজেক্টস' এর একটি তালিকা ফেরত দেয় যেটি আমাকে 'এক্সএমএল অবজেক্টস' এ রূপান্তর করতে হবে, সে কারণেই কি কোনও পরিষেবা স্তর থাকতে যথেষ্ট? একে অন্য ধরণের রূপান্তর করতে এবং একটি নতুন তালিকায় যুক্ত করার জন্য আমি প্রতিটি বস্তুর একটি পদ্ধতি কল করছি
বট_বট

ডাইরেক্ট ডিএও অ্যাক্সেস নিয়ন্ত্রণকারীদের পক্ষে বিপজ্জনক, এটি আপনাকে এসকিউএল ইঞ্জেকশনগুলির জন্য সংবেদনশীল করে তুলতে পারে এবং বিপজ্জনক ক্রিয়াকলাপের অ্যাক্সেস দেয়, ,, মুছে ফেলুন সমস্ত '' আমি অবশ্যই এড়াতে চাই।
অনিরুদ

4

নিয়ন্ত্রকের পক্ষে সরাসরি একটি সংগ্রহস্থল কল করা খারাপ অভ্যাস নয়। একটি "পরিষেবা" হ'ল অন্য একটি সরঞ্জাম, সুতরাং এটি যেখানে এটি বোধগম্য তা ব্যবহার করুন।

নিকোলাইড্যান্ট মন্তব্য করেছেন:

... সঠিক প্রয়োগের জন্য সঠিক প্যাটার্নটি চয়ন করুন। আমি যা বলব তা হ'ল আপনার আবেদনটি সামঞ্জস্য করা উচিত।

আমি মনে করি না ধারাবাহিকতা সবচেয়ে গুরুত্বপূর্ণ দিক। একটি "পরিষেবা" শ্রেণি বোঝানো হয় কিছু উচ্চ স্তরের যুক্তি সজ্জিত করা যাতে নিয়ামককে এটি প্রয়োগ করার প্রয়োজন হয় না। যদি কোনও প্রদত্ত ক্রিয়াকলাপের জন্য "উচ্চ স্তরের যুক্তি" প্রয়োজন না হয় তবে সরাসরি সংগ্রহস্থলে যান।

কনসার্নস এবং টেস্টিবিলিটির ভাল পৃথক পৃথক প্রচারের জন্য, সংগ্রহস্থলটি কোনও কনস্ট্রাক্টরের মাধ্যমে পরিষেবাতে আপনি ইনজেকশনের নির্ভরতা হওয়া উচিত:

IFooRepository repository = new FooRepository();
FooService service = new FooService(repository);

service.DoSomething(...);

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

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

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

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

public class ShoppingCartsController : Controller
{
    [HttpPost]
    public ActionResult Edit(int id, ShoppingCartForm model)
    {
        // Controller initiates a database session and transaction
        using (IStoreContext store = new StoreContext())
        {
            // Controller goes directly to a repository to find a record by Id
            ShoppingCart cart = store.ShoppingCarts.Find(id);

            // Controller creates the service, and passes the repository and/or
            // the current transaction
            ShoppingCartService service = new ShoppingCartService(store.ShoppingCarts);

            if (cart == null)
                return HttpNotFound();

            if (ModelState.IsValid)
            {
                // Controller delegates to a service object to manipulate the
                // Domain Model (ShoppingCart)
                service.UpdateShoppingCart(model, cart);

                // Controller decides to commit changes
                store.SaveChanges();

                return RedirectToAction("Index", "Home");
            }
            else
            {
                return View(model);
            }
        }
    }
}

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

দায়িত্বের ভাঙ্গন এইভাবে চলে:

  • নিয়ামক অ্যাপ্লিকেশনটির প্রবাহ নিয়ন্ত্রণ করে
    • শপিং কার্ট ডাটাবেসে না থাকলে "404 পাওয়া যায় না" ফেরত দেয়
    • বৈধতা ব্যর্থ হলে ফর্মটি বৈধতা বার্তার সাথে পুনরায় রেন্ডার করে
    • সবকিছু চেক আউট হলে শপিং কার্ট সংরক্ষণ করে
  • আপনার ডোমেন মডেলগুলিতে (বা সত্তা) ব্যবসায়িক যুক্তি সম্পাদন করতে নিয়ামক কোনও পরিষেবা শ্রেণিতে প্রতিনিধি। পরিষেবা অবজেক্টগুলি ব্যবসায়ের যুক্তি বাস্তবায়ন করা উচিত নয় ! তারা ব্যবসায়িক যুক্তি কার্যকর করে
  • কন্ট্রোলাররা সাধারণ ক্রিয়াকলাপের জন্য সরাসরি সংগ্রহস্থলগুলিতে প্রতিনিধি দিতে পারে
  • পরিষেবা অবজেক্টগুলি ভিউ মডেলটিতে ডেটা নেয় এবং ব্যবসায়িক যুক্তি সম্পাদনের জন্য ডোমেন মডেলগুলিকে ডেলিগেট দেয় (যেমন, সার্ভিস অবজেক্টটি ডোমেন মডেলগুলিতে সংগ্রহস্থলের পদ্ধতিতে কল করার আগে পদ্ধতিগুলি কল করে)
  • ডেটা অধ্যবসায়ের জন্য পরিষেবা অবজেক্টাগুলি ভান্ডারগুলিতে প্রেরণ করে
  • নিয়ন্ত্রকদের উচিত:
    1. কোনও লেনদেনের আজীবন পরিচালনা করুন, বা
    2. কোনও লেনদেনের আজীবন পরিচালনা করতে ইউনিটের একটি ইউনিট তৈরি করুন

1
-1 একটি রেপো পরিবর্তে নিয়ামক মধ্যে DbContext রাখার জন্য। রেপো হ'ল ডেটা সরবরাহকারীদের পরিচালনা করার জন্য তাই কোনও তথ্য সরবরাহকারী পরিবর্তনের ক্ষেত্রে অন্য কারও প্রয়োজন নেই (উদাহরণস্বরূপ মাইএসকিউএল থেকে ফ্ল্যাট জেএসওন ফাইলগুলিতে এক জায়গায় পরিবর্তিত হওয়া)
জিমি হোফা

@ জিমিহোফা: আমি যে কোডটি লিখেছি তা আসলে ফিরে দেখছি এবং সত্যি বলতে কী, আমি আমার সংগ্রহস্থলের জন্য একটি "প্রসঙ্গ" অবজেক্ট তৈরি করি, প্রয়োজনীয় ডাটাবেস নয়। আমি মনে করি DbContextএই ক্ষেত্রে একটি খারাপ নাম। আমি এটা পরিবর্তন করব। আমি এনএইচবারনেট ব্যবহার করি এবং সংগ্রহস্থলগুলি (বা প্রসঙ্গটি যদি এটি কার্যকর হয়) জিনিসগুলির ডাটাবেস শেষ পরিচালনা করে, তাই অধ্যবসায়িক ব্যবস্থার পরিবর্তনের জন্য প্রসঙ্গের বাইরে কোড পরিবর্তনের প্রয়োজন হয় না।
গ্রেগ বার্গার্ড্ট

আপনার কোডের চেহারা অনুসারে আপনি ভান্ডারগুলির সাথে বিভ্রান্তিকর নিয়ন্ত্রণকারক হয়ে উঠছেন বলে ... মানে আপনার "প্রসঙ্গ" সবই ভুল এবং নিয়ামকের মধ্যে একেবারেই থাকা উচিত নয়।
জিমি হোফা

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

1
একটি সংগ্রহশালা, এটি সাধারণত সমস্ত তথ্য প্রসঙ্গে তথ্যের জন্য দায়ী যে তা নিশ্চিত করতে যে ডোমেন নিজেই যা জানা দরকার তা বাদ দিয়ে ডেটা উদ্বেগের বিষয়ে অন্য কিছু জানার দরকার নেই
জিমি হোফা

1

এটি আপনার আর্কিটেকচারের উপর নির্ভর করে। আমি স্প্রিং ব্যবহার করি এবং লেনদেন সর্বদা পরিষেবাগুলি দ্বারা পরিচালিত হয়।

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

সেই কারণে আমি মনে করি যে সরাসরি নিয়ন্ত্রকদের কাছ থেকে সংগ্রহস্থলগুলি কল করা বা সহজ প্রতিনিধিত্বমূলক পরিষেবাগুলি ব্যবহার করা একটি খারাপ অভ্যাস। আপনি কেবল এটি পড়ার জন্য এটি করা শুরু করেন এবং খুব শীঘ্রই আপনি বা আপনার বা আপনার সঙ্গী এটি লেখার ক্রিয়াকলাপের জন্য এটি করা শুরু করবেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.