কম্পিউটার

সার্ভিস অবজেক্টের সাথে আপনার রেল অ্যাপ রিফ্যাক্টরিং

একটি পরিষেবা বস্তু একটি রুবি বস্তু যা একটি একক ক্রিয়া সম্পাদন করে। এটি আপনার ডোমেন বা ব্যবসায়িক যুক্তিতে একটি প্রক্রিয়া অন্তর্ভুক্ত করে। কল্পনা করুন যে আপনাকে একটি কাল্পনিক লাইব্রেরি অ্যাপ্লিকেশনে একটি বইয়ের উদাহরণ তৈরি করতে হবে; একটি সাধারণ রেল অ্যাপে, আপনি নিম্নলিখিতগুলি করবেন:

class BookController < ApplicationController
  def create
    Book.new(*args)
  end
end

এই সহজ জিনিস জন্য জরিমানা. যাইহোক, অ্যাপের বৃদ্ধির সাথে সাথে আপনি এটির চারপাশে প্রচুর বয়লারপ্লেট নিয়ে আসতে পারেন:

class BookController < ApplicationController
 def create
    default_args = { genre: find_genre(), author: find_author() }
    Book.new(attrs.merge(default_args))
 end

 private

 def find_genre
   // ...
 end

  def find_author
   // ...
 end
end

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

class BookController < ApplicationController
  def
    BookCreator.create_book
  end
end

কেন আপনার পরিষেবার বস্তুর প্রয়োজন

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

আমরা যখন নিম্নলিখিতগুলি সহ ব্যবসায়িক যুক্তিকে এনক্যাপসুলেট করার জন্য পরিষেবাগুলি চালু করি তখন আমরা অনেক সুবিধা পাই:

  • লিন রেল কন্ট্রোলার - নিয়ন্ত্রক শুধুমাত্র অনুরোধগুলি বোঝার জন্য এবং অনুরোধের প্যারাম, সেশন এবং কুকিগুলিকে আর্গুমেন্টে পরিণত করার জন্য দায়ী যা কাজ করার জন্য পরিষেবা বস্তুতে পাস করা হয়। নিয়ামক তারপর পরিষেবা প্রতিক্রিয়া অনুযায়ী পুনঃনির্দেশ বা রেন্ডার করে। এমনকি বড় অ্যাপ্লিকেশনগুলিতে, পরিষেবা বস্তুগুলি ব্যবহার করে কন্ট্রোলার অ্যাকশনগুলি সাধারণত 10 লাইনের বেশি কোড নয়৷

  • পরীক্ষাযোগ্য কন্ট্রোলার - যেহেতু কন্ট্রোলাররা চর্বিহীন এবং পরিষেবার সহযোগী হিসাবে কাজ করে, তাই এটি পরীক্ষা করা সত্যিই সহজ হয়ে যায়, কারণ আমরা শুধুমাত্র পরীক্ষা করতে পারি যে যখন একটি নির্দিষ্ট ক্রিয়া ঘটে তখন কন্ট্রোলারের মধ্যে নির্দিষ্ট পদ্ধতিগুলিকে কল করা হয় কিনা৷

  • বিচ্ছিন্নভাবে ব্যবসায়িক প্রক্রিয়া পরীক্ষা করার ক্ষমতা - পরিষেবাগুলি পরীক্ষা করা সহজ এবং দ্রুত কারণ এগুলি ছোট রুবি বস্তু যা তাদের পরিবেশ থেকে আলাদা করা হয়েছে৷ আমরা সহজেই সমস্ত সহযোগীদের আটকাতে পারি এবং শুধুমাত্র আমাদের পরিষেবার মধ্যে নির্দিষ্ট পদক্ষেপগুলি সম্পাদিত হয়েছে কিনা তা পরীক্ষা করতে পারি৷

  • পুনরায় ব্যবহারযোগ্য পরিষেবাগুলি৷ - পরিষেবা বস্তুগুলিকে কন্ট্রোলার, অন্যান্য পরিষেবা বস্তু, সারিবদ্ধ কাজ, ইত্যাদি দ্বারা কল করা যেতে পারে৷

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

একটি পরিষেবা বস্তু তৈরি করা

প্রথমে, আসুন একটি কাল্পনিক লাইব্রেরি পরিচালনা অ্যাপ্লিকেশনের জন্য অ্যাপ/পরিষেবা নামে একটি নতুন ফোল্ডারে একটি নতুন BookCreator তৈরি করি:

$ mkdir app/services && touch app/services/book_creator.rb

এর পরে, আসুন আমাদের সমস্ত যুক্তি একটি নতুন রুবি ক্লাসের মধ্যে ফেলে দেই:

# app/services/book_creator.rb
class BookCreator
  def initialize(title:, description:, author_id:, genre_id:)
    @title = title
    @description = description
    @author_id = author_id
    @genre_id = genre_id
  end

  def create_book
    Boook.create!(
    title: @title
    description: @description
    author_id: @author_id
    genre_id: @genre_id
    )
    rescue ActiveRecord::RecordNotUnique => e
     # handle duplicate entry
    end
  end
end

তারপর, আমরা কন্ট্রোলারে বা অ্যাপ্লিকেশনের মধ্যে যেকোন জায়গায় পরিষেবা বস্তুটিকে কল করতে পারি:

class BookController < ApplicationController
  def create
    BookCreator.new(title: params[:title], description: params[:description], author_id: params[:author_id], genre_id: params[:genre_id]).create_book
  end
end

সার্ভিস অবজেক্ট সিনট্যাকটিক সুগার

আমরা BookCreator.new(arguments).create সহজ করতে পারি। একটি ক্লাস পদ্ধতি যোগ করে চেইন যা BookCreatorকে ইনস্ট্যান্টিয়েট করে এবং create কে কল করে আমাদের জন্য পদ্ধতি:

# app/services/book_creator.rb
class BookCreator
  def initialize(title:, description:, author_id:, genre_id:)
    @title = title
    @description = description
    @author_id = author_id
    @genre_id = genre_id
  end

  def call(*args)
    new(*args).create_book
  end

  private

  def create_book
    Boook.create!(
    title: @title
    description: @description
    author_id: @author_id
    genre_id: @genre_id
    )
    rescue ActiveRecord::RecordNotUnique => e
     # handle duplicate entry
    end
  end
end

কন্ট্রোলারে, বই নির্মাতাকে এখন নিম্নরূপ বলা যেতে পারে:

class BookController < ApplicationController
  def create
    BookCreator.call(
    title: params[:title],
    description: params[:description],
    author_id: params[:author_id],
    genre_id: params[:genre_id])
  end
end

আমাদের কোড DRY(নিজেকে পুনরাবৃত্তি করবেন না) রাখতে এবং অন্যান্য পরিষেবা বস্তুর সাথে এই আচরণটি পুনরায় ব্যবহার করতে, আমরা call বিমূর্ত করতে পারি একটি বেস ApplicationService এ পদ্ধতি ক্লাস যা প্রতিটি পরিষেবা বস্তু থেকে উত্তরাধিকারী হবে:

class ApplicationService
  self.call(*args)
      new(*args).call
  end
end

এই কোড দিয়ে, আমরা BookCreator রিফ্যাক্টর করতে পারি ApplicationService থেকে উত্তরাধিকারী হতে :

# app/services/book_creator.rb
class BookCreator < ApplicationService
  def initialize(title:, description:, author_id:, genre_id:)
    @title = title
    @description = description
    @author_id = author_id
    @genre_id = genre_id
  end

  def call
    create_book
  end

  private

  def create_book
    # ...
  end
end

বিজনেসপ্রসেস রত্ন ব্যবহার করে পরিষেবা বস্তু তৈরি করা

BusinessProcess রত্ন দিয়ে, আপনাকে একটি বেস অ্যাপ্লিকেশন পরিষেবা ক্লাস তৈরি করতে হবে না বা initialize সংজ্ঞায়িত করতে হবে না পদ্ধতি কারণ রত্নটির মধ্যে এই সমস্ত কনফিগারেশন রয়েছে। আপনার পরিষেবা বস্তুটিকে কেবল BusinessProcess::Base থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হতে হবে .

আপনার রত্ন ফাইলে, নিম্নলিখিত যোগ করুন:

gem 'business_process'

এবং তারপর bundle চালান আপনার টার্মিনালে কমান্ড

class BookCreator < BusinessProcess::Base
  # Specify requirements
  needs :title
  needs :description
   needs :author_id
    needs :genre_id

  # Specify process (action)
  def call
    create_book
  end

   private

  def create_book
    # ...
  end
end

ভাল পরিষেবার বস্তু তৈরি করার নির্দেশিকা

একটি সর্বজনীন পদ্ধতি

একটি পরিষেবা অবজেক্ট একটি ব্যবসায়িক ক্রিয়া সম্পাদন করে এবং এটি ভাল করে বলে অনুমিত হয়, তাই এটি করার জন্য এটি শুধুমাত্র একটি একক সর্বজনীন পদ্ধতি প্রকাশ করা উচিত। অন্যান্য পদ্ধতিগুলি ব্যক্তিগত হওয়া উচিত এবং পাবলিক পদ্ধতিতে বলা উচিত। আপনি যা পছন্দ করেন তা সর্বজনীন পদ্ধতির নামকরণ করতে পারেন, যতক্ষণ না নামকরণ সমস্ত পরিষেবা বস্তুতে সামঞ্জস্যপূর্ণ থাকে। আমাদের উদাহরণে, আমরা এটির নাম দিয়েছি call . অন্যান্য প্রচলিত নাম হল perform এবং execute .

তারা যে ভূমিকা পালন করে সেই অনুযায়ী সার্ভিস অবজেক্টের নাম দিন

একটি পরিষেবা বস্তুর নাম এটি কি করে তা নির্দেশ করা উচিত। "বা" এবং "er" দিয়ে শেষ হওয়া শব্দগুলির সাথে পরিষেবা বস্তুর নামকরণের একটি জনপ্রিয় উপায় রয়েছে। উদাহরণস্বরূপ, যদি পরিষেবা বস্তুর কাজ একটি বই তৈরি করা হয়, তবে এটির নাম দিন BookCreator, এবং কাজটি যদি একটি বই পড়া হয়, তাহলে সেটির নাম দিন BookReader৷

সরাসরি পরিষেবার বস্তুগুলিকে ইনস্ট্যান্টিয়েট করবেন না

কলিং পরিষেবা বস্তুর স্বরলিপি সংক্ষিপ্ত করতে সিনট্যাকটিক চিনির প্যাটার্ন বা বিজনেসপ্রসেসের মতো রত্নগুলির মতো বিমূর্ততা ব্যবহার করুন। এই পদ্ধতির ব্যবহার আপনাকে BookCreator.new(*args).callকে সরল করার অনুমতি দেবে। অথবা BookCreator.new.call(*args) BookCreator.call(*args),-এ যা সংক্ষিপ্ত এবং আরও পাঠযোগ্য।

নেমস্পেসে গ্রুপ সার্ভিস অবজেক্ট

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

services
├── application_service.rb
└── book
├── book_creator.rb
└── book_reader.rb

আমাদের পরিষেবার অবজেক্টগুলি দেখতে এইরকম হবে:

# services/book/book_creator.rb
module Book
  class BookCreator < ApplicationService
  ...
  end
end
# services/twitter_manager/book_reader.rb
module Book
  class BookReader < ApplicationService
  ...
  end
end

আমাদের কলগুলি এখন হয়ে যাবে Book::BookCreator.call(*args) and Book::BookReader.call(*args) .

পরিষেবা বস্তু প্রতি একটি দায়িত্ব

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

উদ্ধার ব্যতিক্রম এবং কাস্টম ব্যতিক্রম বাড়ান

একটি পরিষেবা অবজেক্টের উদ্দেশ্য হল এটির ভিতরে বাস্তবায়নের বিশদগুলিকে এনক্যাপসুলেট করা, যেমন তৃতীয় পক্ষের পরিষেবা বা লাইব্রেরির মধ্যে মিথস্ক্রিয়া বা Rails ActiveRecord এর সাথে ডাটাবেস ম্যানিপুলেশন। যদি একটি ত্রুটি ঘটে, যেমন ActiveRecord::RecordNotUnique, একটি ActiveRecord এর সাথে ইন্টারঅ্যাক্ট করার সময়, পরিষেবাটিকে সঠিকভাবে ব্যতিক্রমটি উদ্ধার করতে হবে। কল স্ট্যাক প্রচার করার জন্য ত্রুটিগুলিকে অনুমতি দেওয়া উচিত নয়৷ যদি রেসকিউ ব্লকের মধ্যে এটি পরিচালনা করা না যায়, তবে সেই পরিষেবা বস্তুর জন্য নির্দিষ্ট একটি কাস্টম-সংজ্ঞায়িত ব্যতিক্রম উত্থাপন করুন৷

উপসংহার

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


  1. Apache JMeter দিয়ে আপনার রেল অ্যাপ লোড পরীক্ষা করুন

  2. আপনার রেল অ্যাপ পরীক্ষা করার জন্য একটি ডকার কন্টেইনার সেট আপ করুন

  3. রেলের সাথে কৌণিক ব্যবহার 5

  4. এই অ্যাপগুলি ব্যবহার করে আপনার ক্যামেরা দিয়ে বস্তুগুলি সনাক্ত করুন