কোনও প্রয়োগের ইন্টারফেস রেফারেন্সটি কাস্ট করে লেখক কী বোঝায়?


17

আমি মাস্টার C # এর চেষ্টা প্রক্রিয়ায় বর্তমানে am, তাই আমি পরছি অভিযোজিত কোড C # এর মাধ্যমে দ্বারা গ্যারি ম্যাকলিন হল

তিনি নিদর্শন এবং বিরোধী নিদর্শন সম্পর্কে লিখেন। ইন্টারফেস অংশ বনাম বাস্তবায়নে তিনি নিম্নলিখিত লিখেছেন:

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

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

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

এটি ভাষার বাধা বা আমার অভিজ্ঞতার অভাব হতে পারে, তবে এর অর্থ কী তা আমি যথেষ্ট বুঝতে পারি না। আমি যা বুঝি তা এখানে:

সি # অনুশীলনের জন্য আমার ফ্রি টাইম মজাদার প্রকল্প রয়েছে। সেখানে আমার একটি ক্লাস রয়েছে:

public class SomeClass...

এই শ্রেণিটি অনেক জায়গায় ব্যবহৃত হয়। সি # শিখার সময়, আমি পড়লাম যে কোনও ইন্টারফেসের সাথে বিমূর্ত করা ভাল, তাই আমি নিম্নলিখিতটি তৈরি করেছি

public interface ISomeClass <- Here I made a "contract" of all the public methods and properties SomeClass needs to have.

public class SomeClass : ISomeClass <- Same as before. All implementation here.

তাই আমি সমস্ত কিছু শ্রেণীর রেফারেন্সে গিয়ে আইসোম ক্লাসের সাথে তাদের প্রতিস্থাপন করেছি।

নির্মাণ ব্যতীত, যেখানে আমি লিখেছি:

ISomeClass myClass = new SomeClass();

আমি কি সঠিকভাবে বুঝতে পারি যে এটি ভুল? যদি হ্যাঁ, তবে কেন, এবং এর পরিবর্তে আমার কী করা উচিত?


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

1
আমি যে কনস্ট্রাক্টরটি লিখেছি সেখানে আপনার অর্থ কী ISomeClass myClass = new SomeClass();? আপনি যদি সত্যিই বোঝাতে চান তবে এটি কনস্ট্রাক্টরের পুনরাবৃত্তি, সম্ভবত আপনি যা চান তা না। আশা করি আপনি "নির্মাণ" অর্থ বরাদ্দ, সম্ভবত, তবে কনস্ট্রাক্টর নিজেই নয়, ঠিক ?
এরিক tদ

@ এরিক: হ্যাঁ নির্মাণে. আপনি সঠিক. প্রশ্ন সংশোধন করবে। ধন্যবাদ
মার্শাল

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

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

উত্তর:


37

আপনার শ্রেণিটিকে একটি ইন্টারফেসে বিমোচন করা এমন কিছু যা আপনার বিবেচনা করা উচিত এবং কেবল যদি আপনি বলেন ইন্টারফেসের অন্যান্য প্রয়োগগুলি লেখার ইচ্ছা করে বা ভবিষ্যতে এমনটি করার দৃ possibility় সম্ভাবনা বিদ্যমান থাকে।

সুতরাং সম্ভবত SomeClassএবং ISomeClassএটি একটি খারাপ উদাহরণ, কারণ এটি OracleObjectSerializerক্লাস এবং IOracleObjectSerializerইন্টারফেস থাকার মতো হবে ।

আরও সঠিক উদাহরণটি হ'ল এর মতো OracleObjectSerializerএবং ক IObjectSerializer। আপনার প্রোগ্রামের একমাত্র জায়গা যেখানে আপনি যখন প্রয়োগটি ব্যবহার করবেন তখন যত্নশীল হ'ল উদাহরণটি তৈরি করা হয়। কখনও কখনও এটি আরও একটি কারখানার নিদর্শন ব্যবহার করে decoupled হয়।

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

এটি সম্পর্কে দুটি উপায় আছে: ভুল উপায় এবং লিসকভ প্রতিস্থাপন নীতি পদ্ধতির।

ভুল উপায়

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

লিসকভ সাবস্টিটিউশন নীতি পদ্ধতির

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

সঠিক পদ্ধতির একটি setPropertyপদ্ধতি প্রদান করা হবে IObjectSerializer। অনুরূপ পদ্ধতিগুলি SQLServerObjectSerializerআদর্শভাবে এই setPropertyপদ্ধতির মাধ্যমে কাজ করবে । আরও ভাল, আপনি Enumপ্রতিটি প্রয়োগকৃত নিজস্ব ডেটাবেস টার্মিনোলজির সমতুল্য হিসাবে অনুবাদ করে এমন জায়গার মাধ্যমে আপনি সম্পত্তির নামগুলিকে প্রমিত করেন ।

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


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

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

@ কেআরয়ান একেবারে। বিমূর্তি কেবল তখনই ব্যবহার করা উচিত যখন আপনার এটির প্রয়োজন হয়। যখন প্রয়োজন হয় না তখন বিমূর্ততা ব্যবহার করা কোডটি বোঝার জন্য কেবল কিছুটা আরও কঠিন করে তোলে।
নীল

29

গৃহীত উত্তরটি সঠিক এবং খুব দরকারী, তবে আমি আপনাকে বিশেষভাবে কোডের লাইনটি সম্পর্কে বিশেষভাবে সম্বোধন করতে চাই:

ISomeClass myClass = new SomeClass();

ব্যাপকভাবে বলতে গেলে, এটি ভয়ানক নয় isn't যে জিনিসটি সম্ভব হলে এড়ানো উচিত:

void someMethod(ISomeClass interface){
    SomeClass cast = (SomeClass)interface;
}

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

এখন, আপনার কনস্ট্রাক্টর কলটির দিকে ফিরে তাকান

ISomeClass myClass = new SomeClass();

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


1
অ্যাপাচি ম্যাথ Cartesian3D উত্স, লাইন 286 দিয়ে এটি করেন যা সত্যই বিরক্তিকর হতে পারে।
J_F_B_M

1
এটি প্রকৃত সঠিক উত্তর যা মূল প্রশ্নকে সম্বোধন করে।
বেনিয়ামিন গ্রুইনবাউম

2

আমি মনে করি একটি খারাপ উদাহরণ সহ আপনার কোডটি দেখানো আরও সহজ:

public interface ISomeClass
{
    void DoThing();
}

public class SomeClass : ISomeClass
{
    public void DoThing()
    {
       // Mine for BitCoin
    }

}

public class AnotherClass : ISomeClass
{
    public void DoThing()
    {
        // Mine for oil
    }
    public Decimal Depth;
 }

 void main()
 {
     ISomeClass task = new SomeClass();

     task.DoThing(); //  This is good

     Console.WriteLine("Depth = {0}", ((AnotherClass)task).Depth); <-- The task object will not have this field
 }

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


কেন হ্যালো স্যার। যে কেউ আপনাকে বলছে আপনি কত সুদর্শন?
নীল

2

কেবল স্বচ্ছতার জন্য, castালাই সংজ্ঞায়িত করা যাক।

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

এই মাইক্রোসফ্ট ডক্স পৃষ্ঠা থেকে কাস্টিংয়ের একটি উদাহরণ এখানে ।

// Create a new derived type.  
Giraffe g = new Giraffe();  

// Implicit conversion to base type is safe.  
Animal a = g;  

// Explicit conversion is required to cast back  
// to derived type. Note: This will compile but will  
// throw an exception at run time if the right-side  
// object is not in fact a Giraffe.  
Giraffe g2 = (Giraffe) a;  

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


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

@hvd আমি কাস্টিংয়ের স্পষ্ট সাক্ষী সম্পর্কে এখন একটি সংশোধন করেছি। যখন আমি বলেছিলাম ডিফল্টটি কেবল বিটগুলির পুনরায় ব্যাখ্যা করতে হবে, তখন আমি প্রকাশ করার চেষ্টা করছিলাম যে আপনি যদি নিজের ধরণের তৈরি করতে চান তবে যেখানে কোনও কাস্ট স্বয়ংক্রিয়ভাবে সংজ্ঞায়িত হয়, আপনি যখন এটি অন্য টাইপে ফেলে দেন তখন বিটগুলি পুনরায় ব্যাখ্যা করা হবে । ইন Animal/ Giraffeউপরোক্ত উদাহরণে, যদি আপনাকে যা করতে ছিল Animal a = (Animal)g;, বিট পুনর্ব্যাখ্যা হবে (যে কোন জিরাফ নির্দিষ্ট ডেটা "এই বস্তুর না অংশ" হিসেবে ব্যাখ্যা করা হবে)।
Ryan1729

এইচডিডি যা বলেছে তা সত্ত্বেও লোকেরা প্রায়শই অন্তর্ভুক্ত রূপান্তরগুলির প্রসঙ্গে "কাস্ট" শব্দটি ব্যবহার করে; উদাহরণস্বরূপ https://www.google.com/search?q="impLive+cast"&tbm=bks দেখুন । প্রযুক্তিগতভাবে আমি মনে করি যে স্পষ্ট রূপান্তরগুলির জন্য "কাস্ট" শব্দটি সংরক্ষণ করা আরও সঠিক, যতক্ষণ না আপনি অন্যরা এটিকে ভিন্নভাবে ব্যবহার করেন তখন আপনি বিভ্রান্ত হন না।
রুখ

0

আমার 5 সেন্ট:

এই সমস্ত উদাহরণ ঠিক আছে, তবে সেগুলি বাস্তব বিশ্বের উদাহরণ নয় এবং প্রকৃত বিশ্বের উদ্দেশ্যগুলি প্রদর্শন করে নি।

আমি সি # জানি না তাই আমি বিমূর্ত উদাহরণ দেব (জাভা এবং সি ++ এর মধ্যে মিশ্রণ)। আশা করি ঠিক আছে।

ধরুন আপনার ইন্টারফেস রয়েছে iList:

interface iList<Key,Value>{
   bool add(Key k, Value v);
   bool remove(Element e);
   Value get(Key k);
}

এখন ধরুন এখানে প্রচুর বাস্তবায়ন হয়েছে:

  • ডায়নামিকআরেলিস্ট - দ্রুত inোকাতে এবং শেষে সরিয়ে নিতে সমতল অ্যারে ব্যবহার করে।
  • লিংকডলিস্ট - সামনে এবং শেষের দিকে সন্নিবেশ করতে ডাবল লিঙ্কযুক্ত তালিকা ব্যবহার করে।
  • AVLTreeList - সব কিছু করার জন্য দ্রুত, AVL ট্রি ব্যবহার করে তবে প্রচুর মেমরি ব্যবহার করে
  • স্কিপলিস্ট - এভিএল গাছের চেয়ে ধীর গতিতে সবকিছু করার জন্য স্কিপলিস্ট ব্যবহার করে, তবে কম স্মৃতি ব্যবহার করে।
  • হ্যাশলিস্ট - হ্যাশ টেবিল ব্যবহার করে

যে কেউ প্রচুর বিভিন্ন বাস্তবায়ন সম্পর্কে ভাবতে পারে।

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

uint begin_size = 1000;
iList list = new DynamicArrayList(begin_size);

এটি পরিষ্কারভাবে আমাদের উদ্দেশ্যটি প্রদর্শন করে যা আমরা ব্যবহার করতে চাই iList। অবশ্যই আমরা আর সঞ্চালন করতে সক্ষম হতে DynamicArrayListনির্দিষ্ট অপারেশন, কিন্তু আমরা একটি প্রয়োজন iList

নিম্নলিখিত কোড বিবেচনা করুন:

iList list = factory.getList();

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


0

আপনার কাছে একটি ইন্টারফেস আইসোমক্লাস রয়েছে, এবং একটি অবজেক্ট মাইওবজেক্ট যার সম্পর্কে আপনি আপনার কোড থেকে কিছুই জানেন না কেবল এটি আইসোম ক্লাস বাস্তবায়নের ঘোষণা করা হয়েছে।

আপনার কাছে একটি ক্লাস সোমারক্লাস রয়েছে, যা আপনি জানেন ইন্টারফেসটি ইসোমক্লাস প্রয়োগ করে। আপনি জানেন যে কারণ এটি ইসোমক্লাস বাস্তবায়নের ঘোষণা করেছে, বা আপনি ইসোমক্লাস বাস্তবায়নের জন্য এটি নিজে প্রয়োগ করেছেন।

আমারক্লাস সোমারক্লাসে কাস্ট করার ক্ষেত্রে কী সমস্যা? দুটি জিনিস ভুল। এক, আপনি সত্যই জানেন না যে মাই ক্লাস এমন একটি জিনিস যা সামার ক্লাসে রূপান্তরিত হতে পারে (সামারক্লাসের উদাহরণ বা সামারক্লাসের একটি সাবক্লাস), যাতে theালাই ভুল হতে পারে। দুই, আপনার এটি করা উচিত নয়। আপনার আইসোমক্লাস হিসাবে ঘোষিত মাইক্লাসের সাথে কাজ করা উচিত, এবং ইসোমক্লাস পদ্ধতিগুলি ব্যবহার করা উচিত।

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

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