কম্পিউটার টিউটোরিয়াল

প্রেজেন্টার ও সার্ভিস অবজেক্ট দিয়ে রেইলস আর্কিটেকচার বানান: প্রমাণিত ডিজাইন প্যাটার্ন

আমাদের ডিজাইন প্যাটার্ন কেন দরকার?

সমস্যাটি হলো রেইলস আর্কিটেকচার, মডেল-ভিউ-কন্ট্রোলার, আপনাকে কোড রাখার একটি বেসিক স্ট্রাকচার দেয়।

কিন্তু এটা যথেষ্ট নয়।

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

আপনার কন্ট্রোলারগুলো কন্ট্রোলারের জন্য অপরিহার্য কাজের বাইরে ডিটেইল ধারণ করে।

সমাধান কী?

এই সমস্যাগুলো সমাধান করার জন্য আমাদের দুটি সমাধান আছে, ডিজাইন প্যাটার্নের রূপে।

  • প্রেজেন্টার প্যাটার্ন
  • সার্ভিস অবজেক্ট প্যাটার্ন

সবাই কীভাবে সঠিকভাবে ইমপ্লিমেন্ট করবেন সেটি নিয়ে একমত নয়, কিন্তু আমি আপনাকে সেই ভার্সন দেবো যা আমার জন্য কাজ করে।

চলুন এই প্যাটার্নগুলো এক্সপ্লোর করি!

রেইলসে প্রেজেন্টার কীভাবে ব্যবহার করবেন

ভিউগুলো প্রেজেন্টেশনের জন্য, অর্থাৎ HTML, CSS, এবং ERB (Embedded Ruby)।

ভিউতে কোনো ActiveRecord ক্যোয়ারী থাকা উচিত নয়।

এবং অधিকাংশ লজিক বাদ দিতে হবে যদি আপনি আপনার ভিউগুলো 최대한 ক্লিন এবং কাজ করার জন্য সহজ রাখতে চান।

"লজিক" বলতে আমি মিনে if স্টেটমেন্ট এবং টার্নারি অপারেটর দিয়ে ডিসিশন মেকিং

এখন প্রশ্ন হলো…

কীভাবে?

ভিউতে লজিক হ্যান্ডেল করার আপনার প্রথম টুল হলো হেল্পারস ব্যবহার করা।

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

উদাহরণ:

Markdown রেন্ডার করা, নির্দিষ্ট ফরম্যাটে তারিখ দেখানো, টেক্সট থেকে নির্দিষ্ট শব্দ সরানো, ইত্যাদি।

এভাবে:

module DateHelper
  def date_as_month_and_year(date)
    date.strftime("%B %Y")
  end
end

আপনি এই কোডটি app/helpers ফোল্ডার এবং date_helper.rb ফাইলে সংরক্ষণ করতে পারেন।

এখানে একটি টিপ:

হেল্পার মেথডে ইনপুট আর্গুমেন্ট হিসেবে পাস করুন, ইনস্ট্যান্স ভেরিয়েবল এর ওপর নির্ভর করবেন না।

এটি আপনাকে অনেক সমস্যা থেকে বাঁচাবে।

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

এগুলো জমা হয়ে যাবে এবং কোনো ধরণের অর্গানাইজেশন থাকবে না।

সমাধান আসছে!

জটিল কন্ডিশনাল ও ফরম্যাটিং মেথডকে প্রেজেন্টার অবজেক্ট দিয়ে রিপ্লেস করুন

মান লিন আপনার কাছে এমন একটি ভিউ আছে:

<p>
  Post title: <%= post.title.gsub("forbidden word", "") %>
  <%= link_to "Read post", post, class: "w-75 p-3 text-#{post.draft? ? "orange" : "green"} border-#{post.draft? ? "orange" : "green"}" %>
</p>

খুব ছোট ভিউ, ঠিক না?

কিন্তু এই টার্নারি অপারেটর এবং ডুপ্লিকেট কোডের কারণে এটি খুব জটিল লাগছে।

ভালো নয়!

চলুন একটি প্রেজেন্টার ক্লাস তৈরি করি এটা সমাধান করতে।

এভাবে:

class PostPresenter
  def initialize(post)
    @post = post
  end

  def title_without_forbidden_words
    @post.title.gsub("forbidden word", "")
  end

  def css_color
    @post.draft? ? "orange" : "green"
  end
end

এটি app/presenters/post_presenter.rb এ সংরক্ষণ করুন, আপনার যদি presenters ফোল্ডার না থাকে তবে তৈরি করুন।

এখন আপনি ভিউ পরিবর্তন করতে পারেন।

এভাবে:

<% presenter = PostPresenter.new(post) %>
<p>
  Post title: <%= presenter.title_without_forbidden_words %>
  <%= link_to "Read post", post, class: "w-75 p-3 text-#{presenter.css_color} border-#{presenter.css_color}" %>
</p>

হয়ে গেলো!

  • আমরা ভিউ থেকে সকল লজিক সরিয়ে ফেললাম
  • ফরম্যাটিং এবং ডিসিশন মেকিং অপারেশনের জন্য অর্থবহ নাম যোগ করলাম
  • এই ক্লাসটি অন্য ভিউতে পুনরাবৃত্তি ছাড়া পুনঃব্যবহার করা যাবে

এইভাবে আপনি রেইলসে প্রেজেন্টার ব্যবহার করেন 🙂

সার্ভিস অবজেক্ট কীভাবে ব্যবহার করবেন

আপনার কন্ট্রোলারগুলো শুধু অন্যদের কী করতে হবে তা বলা উচিত, সেগুলোকে কীভাবে একটি টুইট পাঠাবেন, কাস্টমার চার্জ করবেন বা PDF ফাইল জেনারেট করবেন সেটি জানা উচিত নয়।

এই অপারেশনগুলো ডেলিগেট করা উচিত একটি সার্ভিস অবজেক্টের কাছে।

যেমন আমি ডিফাইন করছি, একটি সার্ভিস অবজেক্ট হলো একটি রুবি মডিউল যা একটি অ্যাকশন কমপ্লিট করার লজিককে এনক্যাপসুলেট করে।

উদাহরণ:

module TwitterService
  def self.send_welcome_message(twitter_handle)
    client.update("@#{twitter_handle} welcome to 'Oranges & Apples', we hope you enjoy our juicy fruit!")
  end

  def self.client
    @client ||= Twitter::REST::Client.new do |config|
      config.consumer_key = "..."
      config.consumer_secret = "..."
      config.access_token = "..."
      config.access_token_secret = "..."
    end
  end
end

কনভেনশন হলো এটিকে app/services ফোল্ডার এবং twitter_service.rb ফাইলে সংরক্ষণ করা।

এটি কীভাবে ব্যবহার করবেন?

রেইলস app/ থেকে সবকुछ অটোলোড করে, তাই এই কোড আপনার কন্ট্রোলারে উপলব্ধ থাকবে।

উদাহরণ:

class UsersController
  def create
    # ...
    TwitterService.send_welcome_message(user.twitter_handle)
  end
end

এই হলো সার্ভিস অবজেক্ট প্যাটার্নের কাজ।

সারসংক্ষেপ

আপনি দুটি সহায়ক রেইলস প্যাটার্ন শিখেছেন যা বুদ্ধিমানভাবে ব্যবহার করলে আপনার প্রজেক্টের কোড কোয়ালিটি উন্নত করবে!

এখন আপনার পালা এগুলো প্রয়োগ করার 🙂

পড়ার জন্য ধন্যবাদ।

  1. ডার্ক প্যাটার্ন কী? ৬ উপায় যাতে আপনার মস্তিষ্ককে ঠকানো হচ্ছে

  2. Hotwire দিয়ে Rails অ্যাপস দ্রুত করুন: JavaScript ছাড়া সার্ভার-সাইড রেন্ডারিং

  3. রুবি অন রেইলস AWS Lambda-তে ডিপ্লয়: ধাপে ধাপে গাইড

  4. Angular এবং Rails 5 ইন্টিগ্রেশন: একটি স্মুথ ফুল-স্ট্যাক পদ্ধতি