কোন শ্রেণির আসল দায়িত্ব কী?


42

আমি ভাবছি যে OOP- এ বিশেষ্যগুলির উপর ভিত্তি করে ক্রিয়াগুলি ব্যবহার করা বৈধ কিনা?
আমি এই উজ্জ্বল নিবন্ধটি জুড়ে এসেছি , যদিও আমি এখনও এটি তৈরির পয়েন্টের সাথে একমত নই।

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

আমার ব্যক্তিগত (এবং হ্যাঁ, খুব নম্র) দৃষ্টিভঙ্গি হ'ল এটি করা একক দায়িত্বের নীতিটি ভঙ্গ করে। আমি যখন পিএইচপি-তে প্রোগ্রাম করেছিলাম (কারণ পিএইচপি স্পষ্টতই ওওপি-র জন্য সেরা ভাষা, তাই না?), আমি প্রায়শই এই ধরণের কাঠামো ব্যবহার করতাম:

<?php

// This is just an example that I just made on the fly, may contain errors

class User extends Record {

    protected $name;

    public function __construct($name) {
        $this->name = $name;
    }

}

class UserDataHandler extends DataHandler /* knows the pdo object */ {

    public function find($id) {
         $query = $this->db->prepare('SELECT ' . $this->getFields . ' FROM users WHERE id = :id');
         $query->bindParam(':id', $id, PDO::PARAM_INT);
         $query->setFetchMode( PDO::FETCH_CLASS, 'user');
         $query->execute();
         return $query->fetch( PDO::FETCH_CLASS );
    }


}

?>

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

আমি এই সি # কোডটি পেরিয়ে এসেছি (ইয়ে, এই পোস্টে ব্যবহৃত চতুর্থ অবজেক্টের ভাষা) ঠিক অন্যদিনে:

byte[] bytes = Encoding.Default.GetBytes(myString);
myString = Encoding.UTF8.GetString(bytes);

এবং আমি বলতে চাই যে এটি আমার কাছে খুব একটা বোঝায় না যে একটি Encodingবা Charsetশ্রেণি আসলে স্ট্রিংগুলি এনকোড করে। এটি কেবল একটি এনকোডিং আসলে কী তা উপস্থাপন করা উচিত।

সুতরাং, আমি যে ভাবা হবে:

  • Fileফাইলগুলি খোলার, পড়া বা সংরক্ষণ করা কোনও শ্রেণির দায়িত্ব নয় ।
  • Xmlনিজেকে ধারাবাহিক করা কোনও শ্রেণির দায়িত্ব নয়।
  • Userডাটাবেসকে জিজ্ঞাসা করা কোনও শ্রেণীর দায়িত্ব নয় ।
  • প্রভৃতি

তবে, আমরা যদি এই ধারণাগুলি বহির্মুখী করি, তবে Objectএকটি toStringক্লাস কেন হবে ? নিজেকে স্ট্রিংয়ে রূপান্তরিত করা কোনও গাড়ি বা কুকুরের দায়িত্ব নয়, এখন তা কি?

আমি বুঝতে পারি যে বাস্তববাদী দৃষ্টিকোণ থেকে, toStringকঠোর SOLID ফর্ম অনুসরণের সৌন্দর্যের জন্য পদ্ধতি থেকে মুক্তি পাওয়া , যা কোডটিকে অকেজো করে তৈরি করে আরও রক্ষণাবেক্ষণ করে তোলে, এটি গ্রহণযোগ্য বিকল্প নয়।

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

একটি শ্রেণীর দায়িত্ব কী?


অবজেক্টস টু স্ট্রিং বেশিরভাগ ক্ষেত্রে সুবিধার্থে, এবং টবস্ট্রিং সাধারণত ডিবাগিংয়ের সময় অভ্যন্তরীণ অবস্থা দ্রুত দেখার জন্য ব্যবহৃত হয়
র‌্যাচেট ফ্রিক

3
@ratchetfreak আমি একমত, তবে এটি উদাহরণ হিসাবে দেখানো (প্রায় একটি রসিকতা) ছিল যে একক দায়বদ্ধতাটি আমি যেভাবে বর্ণনা করেছি তাতে প্রায়শই ভঙ্গ হয়।
পিয়ের আরলাড

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

উত্তর:


24

ভাষার মধ্যে কিছু বিভেদ দেওয়া, এটি একটি জটিল বিষয় হতে পারে। সুতরাং, আমি নীচের ভাষ্যগুলি এমনভাবে তৈরি করছি যাতে ওওয়ের রাজত্বের অভ্যন্তরে আমি যতটা সম্ভব বিস্তৃত হওয়ার চেষ্টা করি।

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

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

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

ঠিক আছে, আমরা অভিজ্ঞতা থেকে জানি যে অনেকগুলি অবজেক্ট (এবং অনেকগুলি শ্রেণি) "অনেক কিছুই" করে বলে মনে হয় তা করার জন্য খুব ভাল কারণ রয়েছে। অনাকাঙ্ক্ষিত কেসটি হ'ল ক্লাসগুলি যা রক্ষণাবেক্ষণের জন্য দুর্ভেদ্য হওয়ার মতো কার্যকরীতার সাথে ফুলে যায় ইত্যাদি। এবং পরে বুঝতে হবে কোথায় মিঃ। মার্টিন লক্ষ্য রেখেছিলেন যখন তিনি এই বিষয়টি বিস্তারিতভাবে বর্ণনা করলেন।

অবশ্যই পড়ার পরে কি মি। মার্টিন লিখেছেন, এগুলি পরিষ্কার হওয়া উচিত যে সমস্যা সমাধানের পরিস্থিতি এড়াতে দিকনির্দেশ এবং নকশার মানদণ্ডগুলি হ'ল, কোনওভাবেই কোনওরকম সম্মতি অনুসরণ করার পক্ষে নয়, দৃ strong় সম্মতিটি একাকী ছেড়ে দিন, বিশেষত যখন "দায়িত্ব" অসুস্থভাবে সংজ্ঞায়িত হয় (এবং প্রশ্নগুলি "যেমন এটি করে থাকে) নীতি লঙ্ঘন? "বিভ্রান্তির নিখুঁত উদাহরণ)। সুতরাং, আমি এটি দুর্ভাগ্যজনক বলে মনে করি এটি একটি নীতি বলা হয়, লোককে বিভ্রান্ত করে এটিকে সর্বশেষ পরিণতিতে নিয়ে যাওয়ার প্রয়াস, যেখানে এটি কোনও ভাল করবে না। মিঃ মার্টিন নিজেই এমন নকশাগুলি নিয়ে আলোচনা করেছিলেন যে "একাধিক কাজ করে" সম্ভবত সেভাবেই রাখা উচিত, যেহেতু পৃথকীকরণের ফলে আরও খারাপ ফল পাওয়া যায়। এছাড়াও, মড্যুলারিটি সম্পর্কিত অনেকগুলি চ্যালেঞ্জ রয়েছে (এবং এই বিষয়টি এটির একটি বিষয়) এটি সম্পর্কে কিছু সাধারণ প্রশ্নের জন্য আমরা এমনকি ভাল উত্তর পাওয়ার পর্যায়ে নেই।

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

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

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

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


31

[দ্রষ্টব্য: আমি এখানে বস্তু সম্পর্কে কথা বলতে যাচ্ছি। অবজেক্টগুলি হ'ল অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের বিষয়ে, সর্বোপরি ক্লাস নয়]]

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

যেমনটি আমরা সবাই জানি, "ক্রিয়া / বিশেষ্য" পদ্ধতিটি যা প্রায়শই প্রবর্তনীয় কোর্সে শেখানো হয় তা হাস্যকর, কারণ আপনি একটি বাক্যটি কীভাবে গঠন করেন তার উপর এটি এতটা নির্ভর করে। আপনি সক্রিয় বা নিষ্ক্রিয় কণ্ঠে কোনও কিছু বিশেষ্য বা ক্রিয়া হিসাবে প্রকাশ করতে পারেন। আপনার ডোমেন মডেলটির উপর নির্ভর করে থাকা ভুল, এটি কোনও সচেতন নকশার পছন্দ হওয়া উচিত যা কোনও জিনিস বা পদ্ধতি বা না হওয়া, আপনি কীভাবে প্রয়োজনীয়তাগুলি নির্ধারণ করেন তার এক आकस्मिक পরিণতি নয়।

যাইহোক, এটা নেই যে দেখাই, ঠিক এরকমই আপনি ইংরেজিতে একই জিনিস প্রকাশ অনেক সম্ভাবনার আছে, আপনি আপনার ডোমেইন মডেল একই জিনিস প্রকাশ অনেক সম্ভাবনার নেই ... এবং যারা সম্ভাবনার কেউ মজ্জাগতভাবে অন্যদের তুলনায় বেশি সঠিক। ইহা পারিপার্শ্বিক অবস্থা উপর নির্ভর করে।

এখানে একটি উদাহরণ রয়েছে যা প্রবর্তক ওও কোর্সে খুব জনপ্রিয়: একটি ব্যাংক অ্যাকাউন্ট। যা সাধারণত একটি balanceক্ষেত্র এবং একটি transferপদ্ধতি সহ একটি বস্তু হিসাবে মডেল করা হয় । অন্য কথায়: অ্যাকাউন্টের ভারসাম্য হ'ল ডেটা এবং ট্রান্সফার হ'ল একটি ক্রিয়াকলাপ । যা কোনও ব্যাংক অ্যাকাউন্টের মডেল করার পক্ষে যুক্তিসঙ্গত উপায়।

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

সম্পর্কে আপনার নির্দিষ্ট প্রশ্ন হিসাবে toString, আমি সম্মত। আমি খুব পছন্দ করি একটি Showable টাইপ শ্রেণীর হাস্কেল সমাধানকে । (স্কেলা আমাদের শিখায় যে প্রকারের ক্লাসগুলি ওওর সাথে সুন্দরভাবে ফিট করে)) সমতার সাথে একই। সাম্যতা প্রায়শই কোনও সামগ্রীর সম্পত্তি নয় তবে সেই প্রসঙ্গে যা বস্তুটি ব্যবহৃত হয়। ভাসমান পয়েন্ট সংখ্যাগুলি সম্পর্কে কেবল চিন্তা করুন: অ্যাপসিলনটি কী হওয়া উচিত? আবার, হাস্কেলের Eqটাইপ ক্লাস রয়েছে।


আমি আপনার হ্যাসেলের তুলনা পছন্দ করি, এটি উত্তরটি আরও কিছুটা… তাজা করে তোলে। আপনি সেই নকশাগুলি সম্পর্কে কী বলবেন যা ActionRecordকোনও মডেল এবং ডেটাবেস রিকোয়েস্টার উভয়কেই অনুমতি দেয় ? প্রসঙ্গটি কোনও বিষয় নয় বলে মনে হচ্ছে এটি একক-দায়িত্ব নীতিটি ভঙ্গ করছে।
পিয়ের আরলাড

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

1
আমি বলব না যে ভার্ব / বিশেষ্য পদ্ধতিটি "হাস্যকর"। আমি বলব যে সরল নকশাগুলি ব্যর্থ হবে এবং এটি সঠিকভাবে পাওয়া খুব কঠিন । কারণ, কাউন্টারেএক্সেমাল, কোনও ভার্চুয়াল / বিশেষ্য পদ্ধতিটি কি কোনও রেস্টস্টুল এপিআই নয়? যেখানে অতিরিক্ত মাত্রার অসুবিধার জন্য ক্রিয়াগুলি অত্যন্ত সীমাবদ্ধ?
user949300

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

8

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

আপনি এটি কখনই নিখুঁত পাবেন না, তবে কোনও শ্রেণীর পক্ষে খুব অল্পের চেয়ে কিছুটা বেশি করা ভাল।

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


7

ক্লাসের উদাহরণ হ'ল বন্ধ। এটাই. আপনি যদি মনে করেন যে আপনি ভালভাবে ডিজাইন করেছেন এমন সমস্ত সফ্টওয়্যার সঠিকভাবে দেখায়, এবং সমস্ত দুর্বল চিন্তাভাবনা করা সফ্টওয়্যারটি দেখতে পাবে না। আমাকে প্রসারিত করুন।

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

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

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

বেশিরভাগ সমস্যাগুলি যা আপনি সমাধান করতে চান সেগুলি এইভাবে স্তরযুক্ত করা হয় - জিনিসগুলি সামনে তৈরি করা হয়, প্রতিটি ধরণের প্রক্রিয়াকরণের লুপের প্রতিটি পুনরাবৃত্তির শুরুতে তৈরি জিনিসগুলি, তারপরে দুটি অংশে আলাদা আলাদা জিনিস ঘোষণা করা হয়, তবে এখানে তৈরি জিনিসগুলি কিছু ধরণের সাব লুপের সূচনা, তারপরে জিনিসগুলি সেই লুপের মধ্যে অ্যালগোরিদমের কিছু অংশ হিসাবে ঘোষিত হয় As স্ট্যাকের নীচে স্তরগুলিতে ডেটা বাক্স আপ করে এমন এক ধরণের সুন্দর বিমূর্ততা তৈরি করে যা অ্যাক্সেসকে সহজ করে তোলে। আপনি যা করছেন তা কার্যকরী প্রোগ্রামিং পদ্ধতির জন্য "ওও" কে এক ধরণের ক্লোজার ম্যানেজমেন্ট কাঠামো হিসাবে ব্যবহার করছেন তা দেখুন।

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

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

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


4

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

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

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

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


4

আমি এই সি # কোডটি পেরিয়ে এসেছি (ইয়ে, এই পোস্টে ব্যবহৃত চতুর্থ অবজেক্টের ভাষা) ঠিক অন্যদিনে:

byte[] bytes = Encoding.Default.GetBytes(myString);
myString = Encoding.UTF8.GetString(bytes);

এবং আমি বলতে চাই যে এটি আমার কাছে খুব একটা বোঝায় না যে একটি Encodingবা Charsetশ্রেণি আসলে স্ট্রিংগুলি এনকোড করে। এটি কেবল একটি এনকোডিং আসলে কী তা উপস্থাপন করা উচিত।

তাত্ত্বিকভাবে, হ্যাঁ, তবে আমি মনে করি যে সি # সরলতার জন্য (জাভার আরও কঠোর পদ্ধতির বিরোধিতা করে) সরলতার জন্য ন্যায়সঙ্গত সমঝোতা করে।

যদি Encodingকেবল নির্দিষ্ট এনকোডিংকেই প্রতিনিধিত্ব করা হয় - বা বলুন, ইউটিএফ -8 - তবে আপনাকে অবশ্যই একটি Encoderশ্রেণির প্রয়োজন হবে, যাতে আপনি এটি প্রয়োগ করতে পারেন GetBytes- তবে তারপরে আপনাকে Encoders এবং Encodings এর মধ্যে সম্পর্ক পরিচালনা করতে হবে , তাই আমরা আমাদের ভাল ওল 'দিয়ে শেষ

EncodersFactory.getDefaultFactory().createEncoder(new UTF8Encoding()).getBytes(myString)

আপনি যে নিবন্ধটিতে লিঙ্ক করেছেন তেমন উজ্জ্বলতার সাথে আলো ছড়িয়েছে (দুর্দান্তভাবে পড়ুন, উপায় দ্বারা)।

যদি আমি আপনাকে ভাল করে বুঝতে পারি তবে আপনি লাইনটি কোথায় তা জিজ্ঞাসা করছেন।

ঠিক আছে, বর্ণালীটির বিপরীত দিকে প্রক্রিয়াগত পদ্ধতি রয়েছে, স্থির শ্রেণীর ব্যবহারের সাথে ওওপি ভাষায় প্রয়োগ করা কঠিন নয়:

HelpfulStuff.GetUTF8Bytes(myString)

এটি সম্পর্কে বড় সমস্যাটি হ'ল যখন আমি লেখকের HelpfulStuffপাতা ছেড়ে চলে যাই এবং আমি মনিটরের সামনে বসে থাকি তখন কোথায় GetUTF8Bytesবাস্তবায়িত হয় তা জানার আমার কোনও উপায় নেই ।

আমি এর মধ্যে জন্য অপেক্ষা করব HelpfulStuff, Utils, StringHelper?

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

আমার কাছে, উপযুক্ত নকশাটি বিমূর্ত মাপদণ্ডকে সন্তুষ্ট করার বিষয়ে নয়, তবে আমি আপনার কোডের সামনে বসার পরে চালিয়ে যাওয়া আমার স্বাচ্ছন্দ্য সম্পর্কে। এখন কিভাবে

EncodersFactory.getDefaultFactory().createEncoder(new UTF8Encoding()).getBytes(myString)

এই দিক থেকে হার? দুর্বল পাশাপাশি। এটি আমার উত্তর নয় যখন আমি আমার সহকর্মীকে চিৎকার করে বলতে চাই "আমি কীভাবে একটি স্ট্রিংকে বাইট সিকোয়েন্সে এনকোড করব?" :)

তাই আমি মাঝারি পদ্ধতির সাথে যেতে এবং একক দায়িত্ব সম্পর্কে উদার হতে চাই। আমি বরং Encodingক্লাস উভয়কেই এক ধরণের এনকোডিং সনাক্তকরণ এবং প্রকৃত এনকোডিং করানোর চেষ্টা করতাম : আচরণ থেকে ডেটা অপ্রয়োজনীয়।

আমি মনে করি এটি একটি ফ্যাকাস প্যাটার্ন হিসাবে চলেছে, যা গিয়ারগুলি গ্রিজ করতে সহায়তা করে। এই বৈধ প্যাটার্নটি কি SOLID লঙ্ঘন করে? একটি সম্পর্কিত প্রশ্ন: ফ্যাসাদ প্যাটার্নটি কি এসআরপি লঙ্ঘন করে?

নোট করুন যে এটি কীভাবে অভ্যন্তরীণভাবে এনকোডড বাইটগুলি প্রয়োগ করা হয় (। নেট লাইব্রেরিতে)। ক্লাসগুলি কেবল সর্বজনীনভাবে দৃশ্যমান নয় এবং কেবলমাত্র এই "সম্মুখ" এপিআই বাইরে প্রকাশিত হয়েছে। এটি সত্য কিনা তা যাচাই করা এতটা কঠিন নয়, আমি এখনই এটি করতে খুব বেশি অলস করছি :) এটি সম্ভবত না তবে এটি আমার বক্তব্যকে অকার্যকর করে না।

অভ্যন্তরীণভাবে আরও তীব্র, আধ্যাত্মিক প্রয়োগ বাস্তবায়নের সময় বন্ধুত্বের স্বার্থে আপনি সর্বজনীনভাবে দৃশ্যমান বাস্তবায়নকে সহজ করতে বেছে নিতে পারেন।


1

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

নিজেকে স্ট্রিংয়ে রূপান্তরিত করা কোনও গাড়ি বা কুকুরের দায়িত্ব নয়, এখন তা কি?

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

বৃহত্তর প্রশ্নের সরাসরি উত্তর দেওয়া কোনও শ্রেণীর দায়িত্ব বিমূর্ততা হিসাবে কাজ করা। এই কাজটি জটিল হতে পারে, তবে এটি বিন্দু ধরনের, একটি বিমূর্ততা ব্যবহার করা সহজ, কম জটিল ইন্টারফেসের পিছনে জটিল জিনিসগুলি আড়াল করা উচিত। এসআরপি হ'ল একটি নকশার গাইডলাইন যাতে আপনি "এই বিমূর্ততাটি কী উপস্থাপন করে?" এই প্রশ্নে আপনি ফোকাস দিন। ধারণা সম্পূর্ণরূপে বিমূর্ত করার জন্য যদি একাধিক ভিন্ন আচরণের প্রয়োজন হয় তবে তা হ'ল।


0

শ্রেণীর একাধিক দায়িত্ব থাকতে পারে। কমপক্ষে ক্লাসিক ডেটা কেন্দ্রিক OOP এ।

আপনি যদি একক দায়িত্বের নীতিটিকে তার সম্পূর্ণ পরিসরে প্রয়োগ করে থাকেন তবে আপনি দায়িত্ব-দায়িত্ব কেন্দ্রিক নকশাগুলি পাবেন যেখানে মূলত প্রতিটি অ-সহায়ক পদ্ধতি তার নিজস্ব শ্রেণীর অন্তর্গত।

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

এই নিষ্কাশিত শ্রেণীর অপারেশন সেগুলির মধ্যে উপস্থিত যেমন উপর ভিত্তি করে খুব বর্ণনামূলক নাম থাকা উচিত <X>Writer, <X>Reader, <X>Builder। নামগুলির মতো <X>Manager, <X>Handlerঅপারেশনটি মোটেও বর্ণনা করে না এবং যদি এগুলি বলা হয় কারণ তাদের মধ্যে একাধিক অপারেশন রয়েছে, তবে আপনি কী অর্জন করেছেন তা পরিষ্কার নয়। আপনি কার্যকারিতাটিকে এর ডেটা থেকে পৃথক করেছেন, আপনি এখনও সেই উত্তোলক শ্রেণিতে এমনকি একক দায়িত্বের নীতিটি ভেঙেছেন এবং আপনি যদি একটি নির্দিষ্ট পদ্ধতি খুঁজছেন তবে আপনি এটি জানেন না যে এটি কোথায় পাবেন (যদি থাকে <X>বা থাকে <X>Manager)।

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

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

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