অভ্যন্তরীণ শ্রেণিতে কেন পাবলিক পদ্ধতি ব্যবহার করবেন?


250

আমাদের প্রকল্পগুলির মধ্যে একটিতে প্রচুর কোড রয়েছে যা দেখতে এরকম দেখাচ্ছে:

internal static class Extensions
{
    public static string AddFoo(this string s)
    {
        if (s == null)
        {
            return "Foo";
        }

        return $({s}Foo);
    }
}

"এই ধরণের পরে জনসমক্ষে প্রচার করা আরও সহজ" ছাড়াও এগুলি করার কোনও স্পষ্ট কারণ আছে কি?

আমি সন্দেহ করি এটি কেবল খুব অদ্ভুত প্রান্তের ক্ষেত্রে (সিলভারলাইটে প্রতিবিম্ব) বা একেবারেই নয় matters


1
আমার অভিজ্ঞতায় এটাই স্বাভাবিক অনুশীলন।
ফগ

2
@ ফগ, ঠিক আছে তবে কেন এটি স্বাভাবিক অনুশীলন? অভ্যন্তরে অভ্যন্তরীণ পদ্ধতিগুলির একগুচ্ছ পরিবর্তন করা মাত্র সহজ? দ্রুত ফিক্স -> পরিবর্তে অভ্যন্তরীণ প্রকারটি চিহ্নিত করুন?
bopapa_1979

এটাই আমি সবসময় ধরে নিয়েছি। আমার কাছে একটি সুচিন্তিত বিশ্লেষণ নেই, তবে কেন আমি উত্তর পোস্ট করি নি।
ফোগ

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

সেই পদ্ধতি কি সমান নয় return s + "Foo";? +অপারেটর ফাঁকা বা খালি স্ট্রিং সম্পর্কে গ্রাহ্য না করে।
মিক্কেল আর। লন্ড

উত্তর:


418

আপডেট: 2014 সালের সেপ্টেম্বরে এই প্রশ্নটি আমার ব্লগের বিষয় ছিল । মহান প্রশ্নের জন্য ধন্যবাদ!

এই প্রশ্নটি নিয়ে নিজেই সংকলক দলের মধ্যেও যথেষ্ট বিতর্ক রয়েছে।

প্রথমে, নিয়মগুলি বোঝা বুদ্ধিমানের কাজ। শ্রেণি বা স্ট্রাক্টের সর্বজনীন সদস্য এমন সদস্য যা এমন যে কোনও কিছুতে অ্যাক্সেসযোগ্য যা এতে থাকা ধরণের অ্যাক্সেস করতে পারে । সুতরাং একটি অভ্যন্তরীণ শ্রেণীর একজন পাবলিক সদস্য কার্যকরভাবে অভ্যন্তরীণ।

সুতরাং এখন, একটি অভ্যন্তরীণ শ্রেণীর দেওয়া, এর সদস্যদের যে আপনি সমাবেশে অ্যাক্সেস করতে চান তা কি জনসাধারণ বা অভ্যন্তরীণ হিসাবে চিহ্নিত করা উচিত?

আমার মতামত: এই জাতীয় সদস্যকে জনসাধারণ হিসাবে চিহ্নিত করুন।

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

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

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

দুর্ভাগ্যক্রমে, এটি সর্বদা সুন্দরভাবে কাজ করে না; উদাহরণস্বরূপ, একটি অভ্যন্তরীণ শ্রেণি যা অভ্যন্তরীণ ইন্টারফেস প্রয়োগ করে এখনও বাস্তবায়নকারী সদস্যদের পাবলিক হিসাবে চিহ্নিত করতে হবে , কারণ তারা শ্রেণীর পাবলিক পৃষ্ঠের অংশ


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

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

2
ইন্টারফেস অংশটি গুরুত্বপূর্ণ - অভ্যন্তরীণ ব্যবহার করে কোনও ইন্টারফেস পদ্ধতি প্রয়োগ করা অসম্ভব, এটি হয় প্রকাশ্য বা স্পষ্টত ইন্টারফেসের ঘোষণা। সুতরাং পাবলিক শব্দটি দুটি অর্থ সহ বোঝা হয়ে গেছে।
মাইকেল Stum

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

3
আপনার ব্লগ পোস্টের গুরুত্বপূর্ণ উক্তি: "আমার পরামর্শটি হল আপনার দলের মধ্যে বিষয়টি নিয়ে আলোচনা করা, সিদ্ধান্ত নেওয়া এবং তারপরে এটি আটকে থাকা" "
বোপাপা_1979

17

বর্গ হয়, তাহলে internal, এটি একটি অভিগম্যতা দৃষ্টিকোণ থেকে কোন ব্যাপার না আপনি একটি পদ্ধতি চিহ্নিত কিনা internalবা public। তবে ক্লাসটি থাকলে আপনি যে ধরণের ব্যবহার করবেন তা ব্যবহার করা এখনও ভাল public

যদিও কেউ কেউ বলেছে যে এটি থেকে স্থানান্তরকে সহজ করে internalদেয় public। এটি পদ্ধতির বর্ণনার অংশ হিসাবেও কাজ করে। Internalপদ্ধতিগুলি সাধারণত নিখরচায় অ্যাক্সেসের জন্য অনিরাপদ হিসাবে বিবেচিত হয়, যখন publicপদ্ধতিগুলি (বেশিরভাগ) ফ্রি গেম হিসাবে বিবেচিত হয়।

ব্যবহার করে internalবাpublicআপনি publicক্লাসে যেমন যেমন , আপনি নিশ্চিত করেছেন যে আপনি কী ধরণের অ্যাক্সেসের প্রত্যাশা রয়েছে তা যোগাযোগ করছেন, পাশাপাশি publicভবিষ্যতে শ্রেণি তৈরি করার জন্য প্রয়োজনীয় কাজটিও সহজ করেছেন ।


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

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

10

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


উত্তর করার জন্য ধন্যবাদ. আমি জেদী হয়ে জোর দিয়ে বলছি যে কোডিং করার সময় "সবকিছু" গুরুত্বপূর্ণ, যদিও :)
bopapa_1979

1
আপনি ঠিক এরিক, এটি মন্তব্য দূরে কিছুটা ছিল। আশা করি আমার উত্তরটির বাকী কিছুটা কার্যকর ছিল। আমি মনে করি এরিক লিপার্টের উত্তরটি আমি প্রকাশ করার চেষ্টা করছিলাম তবে তিনি এটিকে আরও ভালভাবে ব্যাখ্যা করেছিলেন।
আইয়ামান্ড ǤeezeƦ

8

আমি সন্দেহ করি যে "পরে জনসমক্ষে জনসাধারণ করা কি আরও সহজ?" তাই কি.

Scoping নিয়ম মানে পদ্ধতি শুধুমাত্র দৃশ্যমান হবে internal- তাই এটা সত্যিই ব্যাপার কিনা পদ্ধতি চিহ্নিত করা হয়েছে না publicবা internal

এক সম্ভাবনা যে মনে আসে যে ক্লাস হয় ছিল সরকারি ও পরে পরিবর্তন করা হয়েছে internalএবং বিকাশকারী সব পদ্ধতি অভিগম্যতা সংশোধনকারীদের পরিবর্তন করতে বিরক্ত করে নি।


1
সুস্পষ্ট "পাবলিক ক্লাসটি অভ্যন্তরীণ হয়ে উঠল" দৃশ্যের পেরেকের জন্য +1।
bopapa_1979

8

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


2

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


2
: ইতিমধ্যেই একটি সম্পর্কিত প্রশ্ন হল stackoverflow.com/questions/711361/...
মারিও Corchero

0

internalবলেছেন যে সদস্যকে কেবল একই সমাবেশের মধ্যে থেকে অ্যাক্সেস করা যেতে পারে। এই অ্যাসেমব্লির অন্যান্য শ্রেণি internal publicসদস্যকে অ্যাক্সেস করতে পারে তবে কোনও সদস্য privateবা protectedসদস্যকে অ্যাক্সেস করতে পারবে internalনা বা করবে না।


তবে যদি পদ্ধতিগুলি internalপরিবর্তে চিহ্নিত করা হয় public, তবে তাদের দৃশ্যমানতা পরিবর্তন হবে না। আমি বিশ্বাস করি ওপি এটি সম্পর্কে জিজ্ঞাসা করছে।
ওডে

1
@ সাপথেডিংবাট - পোস্টটি সত্যই সঠিক, তবে এটি কি আসলে প্রশ্নের উত্তর দিচ্ছে?
ওডে

1
ঠিক আছে, প্রশ্নটি কেন তাদের সেভাবে চিহ্নিত করুন। আমি সুযোগের বুনিয়াদি বুঝতে পারি। চেষ্টা করার জন্য ধন্যবাদ, যদিও!
bopapa_1979

0

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

internal class SslStreamEx : System.Net.Security.SslStream
{
    public override void Close()
    {
        try
        {
            // Send close_notify manually
        }
        finally
        {
            base.Close();
        }
    }
}

পদ্ধতিটি হওয়া আবশ্যক publicএবং এটি আমাকে ভাবতে internalপেরেছিল যে এরিক লিপার্ট যেমন বলেছিলেন তেমন পদ্ধতিগুলি স্থাপনের পক্ষে আসলেই কোনও যৌক্তিক বিন্দু নেই যতক্ষণ না এরিক লিপার্ট বলেছিলেন।

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


0

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


0

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

এটার মত:

public sealed class MyCurrentlySealedClass
{
    protected void MyCurretlyPrivateMethod()
    {
    }
}

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

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


আমি কঠোরভাবে এটি করতে পছন্দ করি (বা কমপক্ষে কারণে) এরিক লিপার্ট বলেছিলেন। তাঁর নিবন্ধটি অবশ্যই পঠনযোগ্য।
bopapa_1979
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.