আমার রুবি অন রেল প্যাটার্নস এবং অ্যান্টি-প্যাটার্নস সিরিজের শেষ অংশে স্বাগতম। এটা বেশ একটি রাইড লেখা এবং এই বিষয় সব গবেষণা হয়েছে. এই ব্লগ পোস্টে, আমরা বছরের পর বছর ধরে Ruby on Rails অ্যাপ্লিকেশন তৈরি এবং শিপিং করার সময় আমি যে সবচেয়ে সাধারণ সমস্যাগুলির সম্মুখীন হয়েছি সেগুলি নিয়ে যাব৷
আমি এখানে যে ধারণাগুলি দিয়ে যাব সেগুলি কোডের প্রায় যে কোনও জায়গায় প্রযোজ্য৷ সুতরাং সেগুলিকে সাধারণ ধারণা হিসাবে বিবেচনা করুন, মডেল-ভিউ-কন্ট্রোলার প্যাটার্নের সাথে সম্পর্কিত কিছু নয়। আপনি যদি Rails MVC-এর সাথে সম্পর্কিত প্যাটার্ন এবং অ্যান্টি-প্যাটার্নে আগ্রহী হন, তাহলে আপনি মডেল, ভিউ এবং কন্ট্রোলার ব্লগ পোস্টগুলি দেখতে পারেন৷
সুতরাং আসুন সাধারণ সমস্যা এবং টেকওয়েতে ঝাঁপিয়ে পড়ি।
স্বার্থপর বস্তু এবং ডিমিটারের আইন
ডিমিটারের আইন হল একটি হিউরিস্টিক যা এর নাম পেয়েছে যখন একদল লোক ডিমিটার প্রকল্পে কাজ করেছিল। ধারণাটি হল যে আপনার অবজেক্টগুলি ততক্ষণ পর্যন্ত ঠিক থাকে যতক্ষণ না তারা একবারে একটি পদ্ধতিতে কল করে এবং একাধিক পদ্ধতি কলকে চেইন করে না। অনুশীলনে এর অর্থ নিম্নরূপ:
# Bad
song.label.address
# Good
song.label_address
তাই এখন, song
ঠিকানাটি কোথা থেকে এসেছে তা অবজেক্টের আর জানার প্রয়োজন নেই — ঠিকানাটি label
এর দায়িত্ব বস্তু আপনাকে শুধুমাত্র একটি মেথড কল চেইন করতে এবং আপনার বস্তুগুলিকে 'স্বার্থপর' করতে উৎসাহিত করা হচ্ছে যাতে তারা তাদের সম্পূর্ণ তথ্য সরাসরি শেয়ার না করে কিন্তু সাহায্যকারী পদ্ধতির মাধ্যমে।
সৌভাগ্যবশত, Rails-এ, আপনাকে প্রতিনিয়ত একটি সহায়ক পদ্ধতি লিখতে হবে না — আপনি delegate
ব্যবহার করতে পারেন সাহায্যকারী:
def Label < ApplicationModel
belongs_to :song
delegate :address, to: :song
end
আপনি এগিয়ে যেতে পারেন এবং ডেলিগেটের ডক্সে প্রতিনিধি গ্রহণ করে এমন বিকল্পগুলি নিয়ে খেলতে পারেন। কিন্তু ধারণা এবং বাস্তবায়ন বেশ সহজ. ডিমিটারের আইন প্রয়োগ করে, আপনি কাঠামোগত সংযোগ হ্রাস করেন। শক্তিশালী delegate
এর সাথে একসাথে , আপনি এটি কম লাইনে করেন এবং দুর্দান্ত বিকল্পগুলি অন্তর্ভুক্ত করে।
আরেকটি ধারণা যা ডিমিটারের আইনের সাথে খুব মিল তা হল একক-দায়িত্ব নীতি (বা সংক্ষেপে এসআরপি)। এটি বলে যে একটি মডিউল, ক্লাস বা ফাংশন একটি সিস্টেমের একক অংশের জন্য দায়ী হওয়া উচিত। অথবা, অন্যভাবে উপস্থাপিত:
একই কারণে পরিবর্তিত জিনিসগুলিকে একত্রিত করুন। যে জিনিসগুলি বিভিন্ন কারণে পরিবর্তিত হয় সেগুলি আলাদা করুন৷
লোকেদের প্রায়ই SRP সম্পর্কে আলাদা বোঝাপড়া থাকতে পারে, তবে ধারণাটি হল আপনার বিল্ডিং ব্লকগুলিকে একক জিনিসের জন্য দায়ী রাখা। আপনার Rails অ্যাপ প্রসারিত হওয়ার সাথে সাথে SRP অর্জন করা চ্যালেঞ্জিং হতে পারে, কিন্তু রিফ্যাক্টর করার সময় এটি সম্পর্কে সচেতন থাকুন।
বৈশিষ্ট্য যোগ করার সময় এবং LOC বাড়ানোর সময়, আমি দেখেছি যে লোকেরা প্রায়শই দ্রুত সমাধানের জন্য পৌঁছায়। তাহলে চলুন দ্রুত সমাধানের মাধ্যমে চলে যাই।
আমি একজন লোককে চিনি (আপনার কি রুবি রত্ন দরকার?)
আগের দিন যখন Rails একটি আলোচিত বিষয় ছিল, সেখানে ওপেন সোর্স সহযোগিতায় একটি গর্জন ছিল, যেখানে প্রতিটি কোণায় নতুন রুবি রত্ন পপ আপ হচ্ছে (যেমন এটি আজকাল সমস্ত উদীয়মান জাভাস্ক্রিপ্ট লাইব্রেরির সাথে, কিন্তু অনেক ছোট স্কেলে):
👆 মডিউল গণনা থেকে তথ্য।
যাইহোক, একটি সাধারণ পদ্ধতি ছিল আপনার সমস্যা সমাধানের জন্য একটি বিদ্যমান রত্ন খুঁজে বের করা।
এতে কোনো ভুল নেই, তবে আপনি একটি রত্ন ইনস্টল করার সিদ্ধান্ত নেওয়ার আগে আমি কিছু পরামর্শ শেয়ার করতে চাই।
প্রথমে, নিজেকে এই প্রশ্নগুলি জিজ্ঞাসা করুন:
- মণির বৈশিষ্ট্যগুলির কোন অংশ আপনি ব্যবহার করতে যাচ্ছেন?
- সেখানে কি একই ধরনের রত্ন আছে যা 'সহজ' বা আরও আপ-টু-ডেট?
- আপনি কি সহজে এবং আত্মবিশ্বাসের সাথে আপনার প্রয়োজনীয় বৈশিষ্ট্যটি বাস্তবায়ন করতে পারেন?
আপনি যদি রত্ন বৈশিষ্ট্যগুলির সম্পূর্ণ অ্যারে ব্যবহার করার পরিকল্পনা না করেন তবে এটি বাস্তবায়ন করা মূল্যবান কিনা তা মূল্যায়ন করুন। অথবা, যদি রত্নটির বাস্তবায়ন খুব জটিল হয় এবং আপনি বিশ্বাস করেন যে আপনি এটি আরও সহজভাবে করতে পারেন, একটি কাস্টম সমাধান বেছে নিন।
আরেকটি বিষয় যা আমি বিবেচনা করি তা হল রত্নভাণ্ডার কতটা সক্রিয় — কোন সক্রিয় রক্ষণাবেক্ষণকারী আছে কি? শেষ কবে রিলিজ হয়েছিল?
আপনার মণির নির্ভরতার জন্যও সতর্ক হওয়া উচিত। আপনি নির্ভরতার একটি নির্দিষ্ট সংস্করণে আটকে থাকতে চান না, তাই সর্বদা Gemfile.spec
চেক করুন ফাইল রত্ন সংস্করণ নির্দিষ্ট করার রুবিজেমস পদ্ধতির সাথে পরামর্শ করুন।
যখন আমরা রত্নগুলির বিষয়ে আছি, সেখানে একটি সম্পর্কিত ধারণা রয়েছে যা আমি সম্মুখীন করেছি:'এখানে উদ্ভাবিত হয়নি' (বা এনআইএইচ) ঘটনা যা রেল/রুবি বিশ্বের জন্য প্রযোজ্য। আসুন পরবর্তী বিভাগে এটি সম্পর্কে কি তা দেখা যাক।
এখানে উদ্ভাবিত হয়নি (হয়তো আপনার সেই রুবি রত্নটির প্রয়োজন হবে?)
আমার কর্মজীবনে কয়েকটি ঘটনার মধ্যে, আমার অভিজ্ঞতার সুযোগ ছিল লোকেদের (আমি অন্তর্ভুক্ত) 'এখানে উদ্ভাবিত হয়নি' সিন্ড্রোমে পড়ে। ধারণাটি 'চাকা পুনরায় উদ্ভাবন' এর মতো। কখনও কখনও, দল এবং সংস্থাগুলি লাইব্রেরি (রত্ন) বিশ্বাস করে না যা তারা নিয়ন্ত্রণ করতে পারে না। আস্থার অভাব তাদের জন্য একটি ট্রিগার হতে পারে এমন একটি রত্নকে নতুন করে উদ্ভাবনের জন্য যা ইতিমধ্যেই সেখানে রয়েছে৷
কখনও কখনও, NIH অভিজ্ঞতা একটি ভাল জিনিস হতে পারে. একটি ইন-হাউস সমাধান তৈরি করা দুর্দান্ত হতে পারে, বিশেষ করে যদি আপনি এটিকে অন্যান্য সমাধানগুলির তুলনায় উন্নত করেন। আপনি যদি সমাধানটি ওপেন সোর্স করার সিদ্ধান্ত নেন তবে এটি আরও ভাল হতে পারে (রুবি অন রেল বা প্রতিক্রিয়া দেখুন)। কিন্তু আপনি যদি এটির জন্য চাকাটি পুনরায় উদ্ভাবন করতে চান তবে তা করবেন না। চাকা নিজেই ইতিমধ্যে বেশ দুর্দান্ত৷
এই বিষয়টি বেশ জটিল, এবং আপনি যদি কখনও এমন পরিস্থিতিতে পড়েন তবে নিজেকে এই প্রশ্নগুলি জিজ্ঞাসা করুন:
- আমরা কি আত্মবিশ্বাসী যে আমরা বিদ্যমান সমাধানগুলির চেয়ে আরও ভাল সমাধান করতে পারি?
- যদি বিদ্যমান ওপেন-সোর্স সমাধান আমাদের যা প্রয়োজন তার থেকে ভিন্ন হয়, আমরা কি একটি ওপেন-সোর্স অবদান রাখতে এবং এটিকে উন্নত করতে পারি?
- তাছাড়া, আমরা কি ওপেন সোর্স সমাধানের রক্ষণাবেক্ষণকারী হতে পারি এবং সম্ভবত অনেক ডেভেলপারদের জীবন উন্নত করতে পারি?
কিন্তু কখনও কখনও, আপনাকে কেবল নিজের পথে যেতে হবে এবং নিজেই একটি লাইব্রেরি তৈরি করতে হবে। হতে পারে আপনার সংস্থা একটি ওপেন সোর্স লাইব্রেরি লাইসেন্স করা পছন্দ করে না, তাই আপনি নিজের তৈরি করতে বাধ্য হন৷ তবে আপনি যাই করুন না কেন, আমি বলব চাকাটি পুনরায় উদ্ভাবন করা এড়িয়ে চলুন।
ডিউটিতে লাইফগার্ড (অতিরিক্ত উদ্ধারকারী ব্যতিক্রম)
লোকেরা তাদের মূল লক্ষ্যের চেয়ে বেশি ব্যতিক্রম উদ্ধার করে।
এই বিষয়টি আগেরগুলির তুলনায় কোডের সাথে কিছুটা বেশি সম্পর্কিত। এটা কিছু সাধারণ জ্ঞান হতে পারে, কিন্তু এটা সময়ে সময়ে কোড দেখা যেতে পারে. যেমন:
begin
song.upload_lyrics
rescue
puts 'Lyrics upload failed'
end
আমরা যে ব্যতিক্রমটি উদ্ধার করতে চাই তা নির্দিষ্ট না করলে, আমরা এমন কিছু ব্যতিক্রম ধরব যা আমরা পরিকল্পনা করিনি৷
এই ক্ষেত্রে, সমস্যা হতে পারে যে song
বস্তু হল nil
. যখন সেই ব্যতিক্রমটি ত্রুটি ট্র্যাকারে রিপোর্ট করা হয়, তখন আপনি ভাবতে পারেন যে আপলোড প্রক্রিয়ার সাথে কিছু বন্ধ রয়েছে, যদিও বাস্তবে, আপনি সম্পূর্ণ ভিন্ন কিছু অনুভব করছেন৷
সুতরাং, নিরাপদ থাকার জন্য, ব্যতিক্রমগুলি উদ্ধার করার সময়, আপনি ঘটতে পারে এমন সমস্ত ব্যতিক্রমগুলির একটি তালিকা পেয়েছেন তা নিশ্চিত করুন৷ আপনি যদি কোনো কারণে প্রতিটি ব্যতিক্রম পেতে না পারেন, তবে অতিরিক্ত উদ্ধারের চেয়ে আন্ডার রেসকিউ করা ভালো। আপনি যে ব্যতিক্রমগুলি জানেন তা উদ্ধার করুন এবং পরবর্তী পর্যায়ে অন্যদের পরিচালনা করুন।
আপনি খুব বেশি জিজ্ঞাসা করেন (অনেক SQL প্রশ্ন)
এই বিভাগে, আমরা আরেকটি ওয়েব ডেভেলপমেন্ট, রিলেশন-ডাটাবেস সমস্যার মধ্য দিয়ে যেতে যাচ্ছি।
আপনি একটি অনুরোধে অনেকগুলি এসকিউএল কোয়েরি দিয়ে ওয়েব সার্ভারে বোমা মেরেছেন। কিভাবে যে সমস্যা দেখা দেয়? ঠিক আছে, আপনি যদি একটি অনুরোধে একাধিক টেবিল থেকে একাধিক রেকর্ড আনার চেষ্টা করেন তবে এটি ঘটতে পারে। কিন্তু প্রায়শই যা ঘটে তা হল কুখ্যাত N+1 ক্যোয়ারী সমস্যা৷
৷নিম্নলিখিত মডেলগুলি কল্পনা করুন:
class Song < ApplicationRecord
belongs_to :artist
end
class Artist < ApplicationRecord
has_many :songs
end
আমরা যদি একটি ঘরানার এবং তাদের শিল্পীদের কয়েকটি গান দেখাতে চাই:
songs = Song.where(genre: genre).limit(10)
songs.each do |song|
puts "#{song.title} by #{song.artist.name}"
end
কোডের এই অংশটি দশটি গান পেতে একটি SQL কোয়েরি ট্রিগার করবে। এর পরে, প্রতিটি গানের জন্য শিল্পী আনতে একটি অতিরিক্ত SQL ক্যোয়ারী করা হবে। এটি মোট এগারো (11)টি প্রশ্ন।
পরিস্থিতি কল্পনা করুন যদি আমরা আরও গান লোড করি — আমরা সমস্ত শিল্পীকে পাওয়ার চেষ্টা করার জন্য ডাটাবেসটিকে একটি ভারী লোডের নীচে রাখব৷
বিকল্পভাবে, includes
ব্যবহার করুন রেল থেকে:
songs = Song.includes(:artists).where(genre: genre).limit(10)
songs.each do |song|
puts "#{song.title} by #{song.artist.name}"
end
includes
পরে , আমরা এখন শুধুমাত্র দুটি SQL কোয়েরি পাই, আমরা যত গান দেখানোর সিদ্ধান্ত নিই না কেন। কত ঝরঝরে।
আপনি অনেকগুলি এসকিউএল কোয়েরি নির্ণয় করতে পারেন এমন একটি উপায় হল বিকাশে। আপনি যদি একই টেবিল থেকে ডেটা আনয়ন করার জন্য অনুরূপ এসকিউএল কোয়েরির একটি গ্রুপ দেখতে পান, তাহলে সেখানে কিছু ফিশ হচ্ছে। তাই আমি দৃঢ়ভাবে আপনার উন্নয়ন পরিবেশের জন্য SQL লগিং চালু করতে উত্সাহিত করছি৷ এছাড়াও, রেলগুলি ভার্বোস ক্যোয়ারী লগগুলিকে সমর্থন করে যেগুলি কোডে কোথা থেকে একটি ক্যোয়ারী কল করা হয়েছে তা দেখায়৷
যদি লগগুলি দেখা আপনার জিনিস না হয়, বা আপনি আরও গুরুতর কিছু চান, AppSignal এর কর্মক্ষমতা পরিমাপ এবং N+1 ক্যোয়ারী সনাক্তকরণ চেষ্টা করে দেখুন। সেখানে, আপনি একটি চমৎকার সূচক পাবেন যে আপনার সমস্যাটি একটি N+1 কোয়েরি থেকে এসেছে কিনা। এটি নীচে কেমন দেখায় তা এখানে:
সম্মিলিত করুন
এই ব্লগ পোস্ট সিরিজ পড়ার জন্য ধন্যবাদ. আমি আনন্দিত যে আপনি এই আকর্ষণীয় রাইডের জন্য আমার সাথে যোগ দিয়েছেন, যেখানে আমরা সাধারণ সমস্যাগুলির উপর এই চূড়ান্ত ব্লগ পোস্টের আগে, Rails MVC প্যাটার্নের ভিতরে কী কী রয়েছে তা অন্বেষণ করতে রেলের প্যাটার্ন এবং অ্যান্টি-প্যাটার্ন প্রবর্তন করেছি৷
আমি আশা করি আপনি অনেক কিছু শিখেছেন, বা অন্তত সংশোধিত এবং প্রতিষ্ঠিত করেছেন যা আপনি ইতিমধ্যে জানেন। এটা সব মুখস্থ সম্পর্কে জোর করবেন না. আপনি যেকোন ক্ষেত্রে সমস্যায় পড়লে সবসময় সিরিজের সাথে পরামর্শ করতে পারেন।
আপনি অবশ্যই প্যাটার্ন এবং অ্যান্টি-প্যাটার্ন উভয়ের মুখোমুখি হবেন কারণ এই বিশ্ব (এবং সফ্টওয়্যার ইঞ্জিনিয়ারিং বিশেষত) আদর্শ নয়। এটা আপনারও চিন্তা করা উচিত নয়।
নিদর্শন এবং অ্যান্টি-প্যাটার্নগুলি আয়ত্ত করা আপনাকে একজন দুর্দান্ত সফ্টওয়্যার ইঞ্জিনিয়ার করে তুলবে। কিন্তু যা আপনাকে আরও ভাল করে তোলে তা হল সেই প্যাটার্ন এবং ছাঁচগুলি কখন ভাঙতে হবে তা জানা, কারণ এর কোনও নিখুঁত সমাধান নেই৷
যোগদান এবং পড়ার জন্য আবার ধন্যবাদ. পরেরটিতে দেখা হবে — এবং চিয়ার্স!
পি.এস. আপনি যদি রুবি ম্যাজিক পোস্টগুলি প্রেস থেকে বের হওয়ার সাথে সাথে পড়তে চান তবে আমাদের রুবি ম্যাজিক নিউজলেটারে সাবস্ক্রাইব করুন এবং একটি পোস্ট মিস করবেন না!