যেহেতু রুবি একটি অবজেক্ট-ওরিয়েন্টেড ল্যাঙ্গুয়েজ, আমরা পৃথিবীকে বস্তুর একটি সেট হিসাবে মডেল করার প্রবণতা রাখি। আমরা বলি যে দুটি পূর্ণসংখ্যা (x এবং y) একটি বিন্দু, এবং একটি রেখাতে তাদের দুটি রয়েছে৷
যদিও এই পদ্ধতিটি প্রায়ই দরকারী, এটির একটি বড় সমস্যা রয়েছে। এটি অন্য সকলের উপর ডেটার একটি ব্যাখ্যাকে বিশেষাধিকার দেয়। এটি অনুমান করে যে x, এবং y সর্বদা একটি বিন্দু হবে এবং সেল বা ভেক্টর হিসাবে কাজ করার জন্য আপনার কখনই তাদের প্রয়োজন হবে না।
আপনার একটি সেল প্রয়োজন হলে কি হবে? ওয়েল, পয়েন্ট ডেটার মালিক। তাই আপনি পয়েন্টে আপনার সেল পদ্ধতি যোগ করুন। সময়ের সাথে সাথে আপনি একটি পয়েন্ট ক্লাসের সাথে শেষ হয়ে যাবেন যা আলগা-সম্পর্কিত পদ্ধতির একটি জাঙ্ক ড্রয়ার।
জাঙ্ক-ড্রয়ার ক্লাসগুলি এতই সাধারণ যে আমরা প্রায়শই সেগুলিকে অনিবার্য হিসাবে গ্রহণ করি এবং উন্নয়নের জন্য একটি "রিফ্যাক্টরিং" পদক্ষেপ নিয়ে থাকি। কিন্তু যদি আমরা প্রথমে সমস্যাটি এড়াতে পারি?
ওয়েব ডেভেলপমেন্টের প্রথম নিয়ম হল যে আমরা কথা বলি না ব্যবহারকারীর শ্রেণী
যে কোনো যুদ্ধ-কঠোর উত্পাদন রেল অ্যাপের কেন্দ্রে User
নামক একটি শ্রেণীর একটি বিশাল দানব। .
এটা সবসময় যথেষ্ট নির্দোষভাবে শুরু হয়. আপনি লোকেদের লগ ইন করতে দিতে চান৷ আপনাকে তাদের ব্যবহারকারীর নাম এবং পাসওয়ার্ড সংরক্ষণ করতে হবে, যাতে আপনি একটি ক্লাস তৈরি করতে পারেন:
class User
attr_accessor :username, :password, :email, :address
def authenticate!(password)
...
end
end
এটি এত ভাল কাজ করে যে অবশেষে লোকেরা আপনাকে অর্থ দিতে চায়। "ঠিক আছে," আমরা বলি "একজন ব্যবহারকারী মূলত একজন গ্রাহক হিসাবে একই জিনিস তাই আমরা কয়েকটি বৈশিষ্ট্য এবং কয়েকটি পদ্ধতি যোগ করব।"
class User
...
attr_accessor :payment_processor_token, :subscription_plan_id, ...etc
def charge_cc
...
end
end
দারুণ! এখন আমরা কিছু সত্যিকার অর্থ উপার্জন করছি! সিইও সিদ্ধান্ত নিয়েছেন যে তারা ব্যবহারকারীদের যোগাযোগের তথ্য সহ VCard রপ্তানি করতে সক্ষম হবেন যাতে বিক্রয় দল সহজেই সেগুলিকে SalesForce-এ আমদানি করতে পারে। ভিম ফায়ার করার সময়:
class User
...
def export_vcard
...
end
end
আমরা কি করেছি?
আমরা একটি ব্যবহারকারী ক্লাস দিয়ে শুরু করেছি, যার একমাত্র উদ্দেশ্য ছিল প্রমাণীকরণ পরিচালনা করা। এতে অতিরিক্ত পদ্ধতি এবং গুণাবলী যোগ করে, আমরা এটিকে একটি ব্যবহারকারী/সাবস্ক্রাইবার/যোগাযোগ ফ্রাঙ্কেনস্টাইন হাইব্রিডে পরিণত করেছি।
কেন আমরা এই কাজ করতে হবে? আমরা কি নিজেদেরকে ডেভেলপার হিসেবে সম্মান করি না? আমাদের বাবা-মা কি আমাদের যথেষ্ট ভালোবাসেননি? অথবা আমরা এই ডেটা সত্যিই হয় বিশ্বাস করে ব্যর্থতার জন্য নিজেদের সেট আপ করেছি৷ একটি জিনিস, একটি বস্তু?
কেন আমরা বলি যে ব্যবহারকারীর নাম, পাসওয়ার্ড এবং ইমেল ঠিকানার সমন্বয় একটি ব্যবহারকারী? কেন একজন সাবস্ক্রাইবার নয়? বা একটি পরিচিতি? অথবা একজন সেশনহোল্ডার?
ডেটা সম্পর্কে সত্য হল এটি ডেটা
ডেটা কেবল ডেটা। আজ আপনার প্রেমিকের মতো আচরণ করতে হতে পারে। আগামীকাল এটি একটি প্রাক্তন প্রেমিক হতে পারে৷
এলিক্সিরের মতো কার্যকরী ভাষাগুলি এই পদ্ধতিটি গ্রহণ করে। রুবি'স হ্যাশ, অ্যারে, স্ট্রিং ইত্যাদির মতো সাধারণ স্ট্রাকচারে ডেটা সংরক্ষণ করা হয়। আপনি যখন ডেটা দিয়ে কিছু করতে চান আপনি এটি একটি ফাংশনে পাস করেন। যে কোনো ফলাফল সেই ফাংশন থেকে ফেরত দেওয়া হয়।
এটি সহজ শোনাচ্ছে, কিন্তু এই পদ্ধতিটি বিভিন্ন মডিউলে উদ্বেগগুলিকে আলাদা করা খুব সহজ করে তোলে৷
আমরা কীভাবে আমাদের ইউজার সিস্টেমকে এলিক্সিরে তৈরি করতে পারি তার একটি কার্টুন এখানে রয়েছে:
my_user = %{username: "foo", password: ..., phone: ..., payment_token: ...}
my_user = Authentication.authenticate(my_user)
my_user = Subscription.charge(my_user)
my_user = Contact.export_vcard(my_user)
যেহেতু ডেটা কোড থেকে আলাদা, কোনও মডিউলের সেই ডেটার বিশেষাধিকারযুক্ত ব্যাখ্যা নেই৷
এটিকে রুবিতে ফিরিয়ে আনা হচ্ছে
যেহেতু এই পদ্ধতিটি এলিক্সিরে খুব ভাল কাজ করে, কেন রুবিতে এটি গ্রহণ করবেন না? আমাদের User
তৈরি করতে বাধা দেওয়ার কিছু নেই এটির ডেটার জন্য একটি সাধারণ মোড়কের মধ্যে, এবং সমস্ত ব্যবসায়িক যুক্তিকে মডিউলগুলিতে টেনে আনে৷
class User
attr_accessor :username, :password, :email, :address
end
module Authentication
def self.authenticate!(user)
..
end
end
module Subscription
def self.charge(user)
..
end
end
module Contact
def self.export_vcard(user)
..
end
end
এমনকি আপনি User
তৈরি করতে পারেন একটি স্ট্রাকটে ক্লাস করুন, অথবা এটিকে (ধরনের) অপরিবর্তনীয় করতে কোড যোগ করুন।
তাহলে কি?
এই একটি তুচ্ছ পরিবর্তন মত মনে হয়? মানে কি?
যেমনটি আমরা দেখেছি, সাধারণ OO পদ্ধতির বয়স বাড়ার সাথে সাথে সমস্যা রয়েছে। এই বলে যে একটি নির্দিষ্ট শ্রেণীর মালিক ডেটা, যখন আমাদের সেই ডেটা অন্য কোনও উপায়ে ব্যবহার করার প্রয়োজন হয় তখন আমরা সমস্যায় পড়ি৷
মডুলার পদ্ধতিতে, যাইহোক, আচরণ যোগ করা কোন সমস্যা উপস্থাপন করে না। আমরা কেবল একটি নতুন মডিউল তৈরি করি যা ডেটাকে যেভাবে প্রয়োজন তা ব্যাখ্যা করে। এটি করা সহজ কারণ ডেটা এবং কার্যকারিতা সম্পূর্ণ আলাদা৷
৷অন্যান্য পন্থা
জাঙ্ক-ড্রয়ার সমস্যা প্রতিরোধ করার জন্য অন্যান্য পন্থা রয়েছে। ঐতিহ্যগতভাবে, অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং-এ আপনি উত্তরাধিকার এবং সতর্ক রিফ্যাক্টরিংয়ের মাধ্যমে এটি করার চেষ্টা করবেন। 2012 সালে স্যান্ডি মেটজ রুবিতে ব্যবহারিক অবজেক্ট ওরিয়েন্টেড ডিজাইন প্রকাশ করেছে যা অনেক লোককে নির্ভরতা ইনজেকশন ব্যবহার করে বস্তু রচনা শুরু করতে রাজি করেছিল। এমনকি অতি সম্প্রতি, কার্যকরী প্রোগ্রামিংয়ের জনপ্রিয়তা রুবিস্টদের অপরিবর্তনীয় "ডেটা অবজেক্ট" নিয়ে পরীক্ষা-নিরীক্ষা করতে বাধ্য করেছে।
এই সমস্ত পন্থা পরিষ্কার, সুন্দর কোড তৈরি করতে ব্যবহার করা যেতে পারে। যাইহোক যে ক্লাসগুলি সাধারণত ডেটার মালিক হয় তার মানে হল যে ক্লাস কি তার মধ্যে সবসময় উত্তেজনা থাকবে এবং ক্লাস ডাটা দিয়ে কি করে।
আমি সন্দেহ করি যে জাঙ্ক-ড্রয়ারের সমস্যা এড়াতে এই পদ্ধতিগুলি যতই সফল হোক না কেন কোড থেকে তাদের ডিকপলিং ডেটার ফলাফল৷