প্রবন্ধ

সলিড নীতি অনুসারে খোলা / বন্ধ

সফ্টওয়্যার সত্তা (শ্রেণি, মডিউল, ফাংশন, ইত্যাদি) এক্সটেনশনের জন্য উন্মুক্ত হওয়া উচিত, তবে সম্পাদনার জন্য বন্ধ করা উচিত।

সফ্টওয়্যারটি ডিজাইন করা: মডিউল, ক্লাস এবং ফাংশনগুলি এমনভাবে করা যায় যে যখন নতুন কার্যকারিতা প্রয়োজন হয় তখন আমাদের বিদ্যমান কোডটি সংশোধন করা উচিত নয় বরং নতুন কোড লিখতে হবে যা বিদ্যমান কোড ব্যবহার করবে। এটি অদ্ভুত লাগতে পারে, বিশেষত জাভা, সি, সি ++ বা সি # এর মতো ভাষার সাথে যেখানে এটি কেবল উত্স কোডের ক্ষেত্রেই নয়, বাইনারিগুলিতেও প্রযোজ্য। আমরা এমন উপায়ে নতুন বৈশিষ্ট্য তৈরি করতে চাই যাতে বিদ্যমান বাইনারি, এক্সিকিউটেবল বা ডিএলএলগুলির পুনরায় বিতরণের প্রয়োজন হয় না।
SOLID প্রসঙ্গে OCP

 

পরিপূরক এসআরপি এবং ওসিপি

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

 

ওসিপি নীতি লঙ্ঘনের উদাহরণ

খাঁটি প্রযুক্তিগত দৃষ্টিকোণ থেকে, মুক্ত / বন্ধ নীতিটি খুব সহজ। নীচের মতো দুটি শ্রেণীর মধ্যে একটি সহজ সম্পর্ক ওসিপি নীতি লঙ্ঘন করে।

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

পূর্ববর্তী স্কিমের রেফারেন্স সহ, আমরা অনুমান করতে পারি যে যে কোনও শ্রেণি সরাসরি অন্য শ্রেণি ব্যবহার করে, মুক্ত / বন্ধ নীতি লঙ্ঘনের দিকে পরিচালিত করতে পারে। 
ধরা যাক আমরা একটি অ্যাপ্লিকেশনটির মাধ্যমে একটি ডাউনলোড করা ফাইলের "শতাংশে" অগ্রগতি সরবরাহ করতে সক্ষম একটি ক্লাস লিখতে চাই। আমাদের দুটি প্রধান ক্লাস থাকবে, একটি অগ্রগতি এবং একটি ফাইল, এবং আমি অনুমান করি যে আমরা সেগুলি নীচে ব্যবহার করতে চাই:

 

ফাংশন পরীক্ষাআইটিক্যানগেটপ্রেগ্রিফসফিলএএসএপিয়ারসেন্ট () {
     $ ফাইল = নতুন ফাইল ();
     $ ফাইল-> দৈর্ঘ্য = 200;
     $ ফাইল-> প্রেরণ = 100;
     $ অগ্রগতি = নতুন অগ্রগতি ($ ফাইল);
     $ এটি-> assertEquals (50, $ অগ্রগতি-> getAsPercent ());
}

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

 

ক্লাস ফাইল {
     পাবলিক দৈর্ঘ্য;
     সর্বজনীন $ প্রেরণ;
}

 

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

 

বর্গ অগ্রগতি {

     ব্যক্তিগত $ ফাইল;

     ফাংশন __ কনস্ট্রাক্ট (ফাইল $ ফাইল) {
          $ এই-> ফাইল = $ ফাইল;
     }

     ফাংশন getAsPercent () {
          ফিরুন - এই-> ফাইল-> প্রেরণ * 100 / $ এটি-> ফাইল-> দৈর্ঘ্য;
     }

}

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

এই কোডটি সঠিক বলে মনে হচ্ছে, তবে এটি মুক্ত / বন্ধ নীতি লঙ্ঘন করে।

কিন্তু কেন?

এবং কিভাবে?

 

প্রয়োজনীয়তা পরিবর্তন করার চেষ্টা করা যাক

সময়ের সাথে বিবর্তিত প্রতিটি অ্যাপ্লিকেশনটির নতুন বৈশিষ্ট্য প্রয়োজন। আমাদের অ্যাপ্লিকেশনটির জন্য একটি নতুন বৈশিষ্ট্য হ'ল কেবল ফাইলগুলি ডাউনলোড করার পরিবর্তে সংগীত স্ট্রিমিংয়ের অনুমতি দেওয়া। ফাইলটির দৈর্ঘ্য বাইটে উপস্থাপিত হয়, সংগীতটির সেকেন্ডে সময়কাল। আমরা আমাদের শ্রোতাদের একটি অগ্রগতি বার অফার করতে চাই, কিন্তু আমরা কি উপরে লেখা ক্লাসটি পুনরায় ব্যবহার করতে পারি?

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

 

উদ্ভাবন নিউজলেটার
উদ্ভাবনের সবচেয়ে গুরুত্বপূর্ণ খবর মিস করবেন না। ইমেল দ্বারা তাদের পেতে সাইন আপ করুন.

সম্ভাব্য সমাধান

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

বর্গ অগ্রগতি {

     ব্যক্তিগত $ ফাইল;

     ফাংশন __ কনস্ট্রাক্ট ($ ফাইল) {
         $ এই-> ফাইল = $ ফাইল;
     }

    ফাংশন getAsPercent () {
         ফিরুন - এই-> ফাইল-> প্রেরণ * 100 / $ এটি-> ফাইল-> দৈর্ঘ্য;
     }

}

আমরা এখন অগ্রগতিতে যে কোনও কিছুই চালু করতে পারি। এবং যে কোনও অর্থ, আমি আক্ষরিক অর্থ:

ক্লাস সংগীত {

পাবলিক দৈর্ঘ্য;
সর্বজনীন $ প্রেরণ;

পাবলিক $ শিল্পী;
সর্বজনীন $ অ্যালবাম;
পাবলিক-রিলিজডেট;

অ্যালবামকভারফাইলে ফাংশন () {
'চিত্র / কভার /' ফিরিয়ে দিন। $ এই-> শিল্পী। '/'। $ এটি-> অ্যালবাম। '.png';
}
}

এবং উপরের মতো মিউজিক ক্লাস পুরোপুরি কার্যকর করবে। আমরা খুব সহজেই ফাইলের অনুরূপ একটি পরীক্ষা দিয়ে এটি পরীক্ষা করতে পারি।
ফাংশন পরীক্ষাআইটিক্যানগেটপোগ্রেসঅফ্যামিউজিক স্ট্রিমএএসপিয়ারসেন্ট () {
$ সংগীত = নতুন সংগীত ();
$ সংগীত-> দৈর্ঘ্য = 200;
$ সংগীত-> প্রেরণ = 100;

$ অগ্রগতি = নতুন অগ্রগতি ($ সঙ্গীত);

$ এটি-> assertEquals (50, $ অগ্রগতি-> getAsPercent ());
}

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

বর্গ অগ্রগতি {

ব্যক্তিগত $ পরিমাপযোগ্য

ফাংশন __ কনস্ট্রাক্ট ($ পরিমাপযোগ্য কনটেন্ট) {
$ এটি-> পরিমাপযোগ্য কনটেন্ট = $ পরিমাপযোগ্য কনটেন্ট;
}

ফাংশন getAsPercent () {
রিটার্ন - এটি-> পরিমাপযোগ্য কনটেন্ট-> প্রেরণ * 100 / $ এটি-> পরিমাপযোগ্য কনটেন্ট-> দৈর্ঘ্য;
}

}

আমরা যখন ফাইলটিকে টাইপহিন্ট হিসাবে নির্দিষ্ট করেছি, আমরা আমাদের শ্রেণি কী পরিচালনা করতে পারে সে সম্পর্কে আমরা আশাবাদী ছিলাম। এটি সুস্পষ্ট ছিল এবং অন্য কিছু এলে একটি বড় ভুল আমাদের জানাত tell

Uনা ক্লাস যা বেস ক্লাসের কোনও পদ্ধতিকে ওভাররাইড করে যাতে বেস ক্লাস চুক্তিটি উত্পন্ন শ্রেণীর দ্বারা সম্মানিত না হয়। 

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

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

এই সমাধানটি কেবলমাত্র তখনই সুপারিশ করা হয় যদি নীচে অন্য টিপসের কোনওটিই সহজেই প্রয়োগ করা যায় না বা যদি তারা গুরুতর স্থাপত্য পরিবর্তনগুলি চাপিয়ে দেয় যা চেষ্টার নিশ্চয়তা দেয় না।

Ercole Palmeri

উদ্ভাবন নিউজলেটার
উদ্ভাবনের সবচেয়ে গুরুত্বপূর্ণ খবর মিস করবেন না। ইমেল দ্বারা তাদের পেতে সাইন আপ করুন.

সাম্প্রতিক নিবন্ধ

সুরক্ষা থেকে প্রতিক্রিয়া এবং পুনরুদ্ধার পর্যন্ত র্যানসমওয়্যারের জন্য Veeam সর্বাধিক ব্যাপক সমর্থন বৈশিষ্ট্যযুক্ত

Veeam-এর কভওয়্যার সাইবার চাঁদাবাজি ঘটনার প্রতিক্রিয়া পরিষেবা প্রদান করতে থাকবে। Coveware ফরেনসিক এবং প্রতিকার ক্ষমতা প্রদান করবে...

23 এপ্রিল 2024

সবুজ এবং ডিজিটাল বিপ্লব: কীভাবে ভবিষ্যদ্বাণীমূলক রক্ষণাবেক্ষণ তেল ও গ্যাস শিল্পকে রূপান্তরিত করছে

ভবিষ্যদ্বাণীমূলক রক্ষণাবেক্ষণ তেল ও গ্যাস খাতে বিপ্লব ঘটাচ্ছে, উদ্ভিদ ব্যবস্থাপনায় একটি উদ্ভাবনী এবং সক্রিয় পদ্ধতির সাথে।…

22 এপ্রিল 2024

ইউকে অ্যান্টিট্রাস্ট নিয়ন্ত্রক GenAI এর উপর BigTech এলার্ম উত্থাপন করেছে

ইউকে সিএমএ কৃত্রিম বুদ্ধিমত্তার বাজারে বিগ টেকের আচরণ সম্পর্কে একটি সতর্কতা জারি করেছে। সেখানে…

18 এপ্রিল 2024

কাসা গ্রিন: ইতালিতে টেকসই ভবিষ্যতের জন্য শক্তি বিপ্লব

ভবনগুলির শক্তি দক্ষতা বাড়ানোর জন্য ইউরোপীয় ইউনিয়ন দ্বারা প্রণয়ন করা "গ্রিন হাউস" ডিক্রি, এর আইনী প্রক্রিয়া শেষ করেছে...

18 এপ্রিল 2024

আপনার ভাষায় উদ্ভাবন পড়ুন

উদ্ভাবন নিউজলেটার
উদ্ভাবনের সবচেয়ে গুরুত্বপূর্ণ খবর মিস করবেন না। ইমেল দ্বারা তাদের পেতে সাইন আপ করুন.

আমাদের অনুসরণ