আমার কি বিমূর্ত বা ভার্চুয়াল পদ্ধতি ব্যবহার করা উচিত?


11

যদি আমরা ধরে নিই যে বেস ক্লাসের জন্য খাঁটি ইন্টারফেস শ্রেণি হওয়া বাঞ্ছনীয় নয় এবং নীচে থেকে 2 টি উদাহরণ ব্যবহার করে, যা বিমূর্ত বা ভার্চুয়াল পদ্ধতি শ্রেণীর সংজ্ঞাটি ব্যবহার করে আরও ভাল পদ্ধতির?

  • "বিমূর্ত" সংস্করণটির সুবিধাটি হ'ল এটি সম্ভবত পরিষ্কার দেখায় এবং উদ্ভূত শ্রেণিকে আশার অর্থপূর্ণ বাস্তবায়ন করতে বাধ্য করে।

  • "ভার্চুয়াল" সংস্করণটির সুবিধা হ'ল এটি সহজেই অন্যান্য মডিউলগুলির দ্বারা টানা যায় এবং বিমূর্ত সংস্করণের মতো অন্তর্নিহিত কাঠামোর একটি গুচ্ছ যুক্ত না করে পরীক্ষার জন্য ব্যবহার করা যেতে পারে।

বিমূর্ত সংস্করণ:

public abstract class AbstractVersion
{
    public abstract ReturnType Method1();        
    public abstract ReturnType Method2();
             .
             .
    public abstract ReturnType MethodN();

    //////////////////////////////////////////////
    // Other class implementation stuff is here
    //////////////////////////////////////////////
}

ভার্চুয়াল সংস্করণ:

public class VirtualVersion
{
    public virtual ReturnType Method1()
    {
        return ReturnType.NotImplemented;
    }

    public virtual ReturnType Method2()
    {
        return ReturnType.NotImplemented;
    }
             .
             .
    public virtual ReturnType MethodN()
    {
        return ReturnType.NotImplemented;
    }

    //////////////////////////////////////////////
    // Other class implementation stuff is here
    //////////////////////////////////////////////
}

কেন আমরা ধরে নিচ্ছি যে একটি ইন্টারফেসটি কাম্য নয়?
অ্যান্টনি পেগ্রাম

আংশিক সমস্যা ছাড়াই বলা শক্ত যে, একজনের চেয়ে অপরটির চেয়ে ভাল।
কোডিজম

@ অ্যান্টনি: একটি ইন্টারফেসটি পছন্দসই নয় কারণ দরকারী কার্যকারিতা রয়েছে যা এই শ্রেণিতেও যাবে।
ডাঙ্ক

4
return ReturnType.NotImplemented? সিরিয়াসলি? আপনি যদি সংকলনের সময় অযুহিত প্রকারটি প্রত্যাখ্যান করতে না পারেন (আপনি পারেন; বিমূর্ত পদ্ধতি ব্যবহার করতে পারেন) কমপক্ষে একটি ব্যতিক্রম ছুঁড়ে ফেলুন।
জানু হুডেক

3
@Dunk: এখানে তারা হয় প্রয়োজনীয়। রিটার্ন মানগুলি চেক করা হবে
জানু হুডেক

উত্তর:


15

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


অপ্রত্যাশিতভাবে নোটআইপ্লিমেন্টেড ত্রুটি পাওয়ার বিষয়ে ভাল বিষয়। যা বিমূর্ত দিকের একটি প্লাস, কারণ আপনি রান-টাইম ত্রুটির পরিবর্তে একটি সংকলন-সময় পাবেন।
ডঙ্ক

3
+1 - তাড়াতাড়ি ব্যর্থ হওয়ার সাথে সাথে উত্তরাধিকারীরা অবিলম্বে দেখতে পাবে যে তারা "যথেষ্ট পরিমাণে বিবেচনা করে এবং তারপরে রানটাইমে ব্যর্থ হওয়ার পরিবর্তে" প্রয়োগ বিমূর্ত শ্রেণির মাধ্যমে কী কী পদ্ধতি প্রয়োগ করতে হবে।
টেলাস্টিন

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

25

ভার্চুয়াল সংস্করণ উভয় বাগ প্রবণ এবং শব্দার্থগতভাবে ভুল।

বিমূর্তিটি বলছে "এই পদ্ধতিটি এখানে প্রয়োগ করা হয়নি this এই শ্রেণীর কাজটি করার জন্য আপনাকে অবশ্যই এটি প্রয়োগ করতে হবে"

ভার্চুয়াল বলছে "আমার একটি ডিফল্ট বাস্তবায়ন আছে তবে আপনি প্রয়োজন হলে আমাকে পরিবর্তন করতে পারেন"

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


3

এটি আপনার শ্রেণীর ব্যবহারের উপর নির্ভর করে।

যদি পদ্ধতিগুলির কিছু যুক্তিসঙ্গত "শূন্য" বাস্তবায়ন হয়, আপনার প্রচুর পদ্ধতি রয়েছে এবং আপনি প্রায়শই কেবল কয়েকটিকে ওভাররাইড করে থাকেন, তবে virtualপদ্ধতিগুলি ব্যবহার করে বোঝা যায়। উদাহরণস্বরূপ ExpressionVisitorএইভাবে বাস্তবায়ন করা হয়।

অন্যথায়, আমার মনে হয় আপনার abstractপদ্ধতিগুলি ব্যবহার করা উচিত ।

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


আমি নোট করব যে "নটইম্প্লিমেটেড এক্সসেপশন" প্রায়শই বাদ পড়ার ত্রুটি নির্দেশ করে, যেখানে "নটসম্পোর্টড এক্সসেপশন" একটি ওভারট পছন্দকে নির্দেশ করে। তা ছাড়া আমিও একমত।
অ্যান্টনি পেগ্রাম

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

1

আমি আপনাকে পরামর্শ দিচ্ছি যে আপনার বেস ক্লাসটি প্রয়োগ করে এমন একটি পৃথক ইন্টারফেস সংজ্ঞায়িত করে পুনরায় বিবেচনা করুন এবং তারপরে আপনি বিমূর্ত পদ্ধতির অনুসরণ করুন।

ইমেজিং কোড এর মতো:

public interface IVersion
{
    ReturnType Method1();        
    ReturnType Method2();
             .
             .
    ReturnType MethodN();
}

public abstract class AbstractVersion : IVersion
{
    public abstract ReturnType Method1();        
    public abstract ReturnType Method2();
             .
             .
    public abstract ReturnType MethodN();

    //////////////////////////////////////////////
    // Other class implementation stuff is here
    //////////////////////////////////////////////
}

এটি করা এই সমস্যাগুলি সমাধান করে:

  1. অ্যাবস্ট্রাক্ট ভার্সন থেকে প্রাপ্ত অবজেক্টগুলিকে ব্যবহার করে এমন সমস্ত কোড থাকার পরিবর্তে এখন IVersion ইন্টারফেস পাওয়ার জন্য প্রয়োগ করা যেতে পারে, এর অর্থ তারা আরও সহজে ইউনিট পরীক্ষিত হতে পারে।

  2. আপনার পণ্যের 2 টি রিলিজ আপনার বিদ্যমান গ্রাহকদের কোড ভঙ্গ না করে অতিরিক্ত কার্যকারিতা সরবরাহ করার জন্য একটি ইন্টারফেস IVersion2 প্রয়োগ করতে পারে।

যেমন।

public interface IVersion
{
    ReturnType Method1();        
    ReturnType Method2();
             .
             .
    ReturnType MethodN();
}

public interface IVersion2
{
    ReturnType Method2_1();
}

public abstract class AbstractVersion : IVersion, IVersion2
{
    public abstract ReturnType Method1();        
    public abstract ReturnType Method2();
             .
             .
    public abstract ReturnType MethodN();
    public abstract ReturnType Method2_1();

    //////////////////////////////////////////////
    // Other class implementation stuff is here
    //////////////////////////////////////////////
}

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


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

এবং উত্তম শ্রেণীর নামের সাথে উত্তরাধিকার ব্যবহার করা ক্লাসগুলি (এবং এভাবে সিস্টেম) সহজেই ক্লাসিক ইন্টারফেস শ্রেণীর নামগুলির একগুচ্ছ যা পুরো মানসিকভাবে একত্রে বাঁধা মুশকিল, তার চেয়ে আরও বেশি স্বজ্ঞাত উপায় সরবরাহ করে provides এছাড়াও, ইন্টারফেস ক্লাস ব্যবহার করে আরও এক টন অতিরিক্ত ক্লাস তৈরি করা যায়, যার ফলে সিস্টেমটিকে অন্য কোনও উপায়ে বোঝা আরও শক্ত হয়ে যায়।
ডঙ্ক

-2

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


1
এই অফারটি কোন কিছুরই সৃষ্টি পয়েন্ট উপর সারগর্ভ বলে মনে হচ্ছে না এবং পূর্বে 5 উত্তর ব্যাখ্যা
মশা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.