একাধিক ইন্টারফেস একত্রিত করতে খালি ইন্টারফেস


20

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

interface Readable {
    public void read();
}

interface Writable {
    public void write();
}

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

// can't write to it without explicit casting
Readable myObject = new MyObject();

// can't read from it without explicit casting
Writable myObject = new MyObject();

// tight coupling to actual implementation
MyObject myObject = new MyObject();

এই বিকল্পগুলির কোনওটিই মারাত্মকভাবে সুবিধাজনক নয়, এমনকি এটি বিবেচনা করার সময় আপনি কোনও পদ্ধতি পরামিতি হিসাবে এটি চান।

একটি সমাধান হ'ল একটি মোড়ানো ইন্টারফেস ঘোষণা করা:

interface TheWholeShabam extends Readable, Writable {}

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

এই সমস্যার কোনও পরিষ্কার সমাধান আছে নাকি আমার মোড়কের ইন্টারফেসের জন্য যাওয়া উচিত?

হালনাগাদ

আসলে প্রায়শই এমন কোনও বিষয় থাকা প্রয়োজন যা পাঠযোগ্য এবং লিখিত উভয়ই তাই সহজেই যুক্তিগুলির মধ্যে উদ্বেগগুলি পৃথক করে রাখা সবসময় একটি পরিষ্কার সমাধান নয়।

UPDATE2

(উত্তর হিসাবে উত্তোলন করা হয়েছে যাতে এটিতে মন্তব্য করা সহজ)

UPDATE3

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

UPDATE4

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

ধরুন আপনার কাছে এমন কোনও ক্লাস রয়েছে যা টাইপটি ফেরত দিতে হবে:

public <RW extends Readable & Writable> RW getItAll();

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

MyObject myObject = someInstance.getItAll();

এটি কাজ করবে কিন্তু আবার এটি বাস্তবায়নের সাথে যুক্ত করে এবং আসলে রানটাইমে ক্লাসকস্টেক্সেপশন ফেলে দিতে পারে (কী ফিরে আসে তার উপর নির্ভর করে)।

অতিরিক্তভাবে আপনি যদি আরডাব্লু প্রকারের শ্রেণির পরিবর্তনশীল চান তবে আপনার শ্রেণি স্তরে জেনেরিকটি সংজ্ঞায়িত করতে হবে।


5
বাক্যাংশটি "পুরো শেবাং"
কেভিন cline

এটি একটি ভাল প্রশ্ন, তবে আমি মনে করি আপনার পাঠ্যযোগ্য এবং 'লিখনযোগ্য' ব্যবহার হিসাবে আপনার উদাহরণস্বরূপ ইন্টারফেসগুলি জলকে কিছুটা
হতাশায় পরিণত

@ বসুয়েতা নামকরণ সরল করার সময়, পঠনযোগ্য এবং লিখিতভাবে আমার ব্যবহারের হাতটি বেশ ভালভাবে জানানো হয়েছে। কিছু ক্ষেত্রে আপনি কেবল পড়তে চান, কিছু ক্ষেত্রে কেবল লিখুন এবং আশ্চর্যজনক পরিমাণে পড়ুন এবং লিখুন।
nablex

আমি এমন এক সময়ের কথা ভাবতে পারি না যখন আমার একটি একক প্রবাহ প্রয়োজন যা পাঠযোগ্য এবং রচনামূলক উভয়ই এবং অন্য লোকের উত্তর / মন্তব্য থেকে বিচার করা আমি মনে করি না আমিই একমাত্র one আমি কেবল বলছি এটি কম বিতর্কিত জোড় ইন্টারফেস বেছে নেওয়া আরও সহায়ক হতে পারে ...
ভঘানড্রয়েড

@ বাউকেটা java.nio * প্যাকেজগুলির সাথে কিছু করার আছে? আপনি যদি স্ট্রিমগুলিতে লেগে থাকেন তবে ইউসকেসটি এমন জায়গাগুলির মধ্যেই সীমাবদ্ধ যেখানে আপনি বাইটআরে * স্ট্রিম ব্যবহার করবেন।
nablex

উত্তর:


19

হ্যাঁ, আপনি আপনার পদ্ধতির পরামিতিটিকে একটি অপ্রকাশিত টাইপ হিসাবে ঘোষণা করতে পারেন যা উভয়ই প্রসারিত করে Readableএবং Writable:

public <RW extends Readable & Writable> void process(RW thing);

পদ্ধতির ঘোষণাটি ভয়ঙ্কর দেখাচ্ছে, তবে ইউনিফাইড ইন্টারফেস সম্পর্কে জানার চেয়ে এটি ব্যবহার করা সহজ।


2
আমি এখানে কোনারাডসের দ্বিতীয় পদ্ধতির অনেক পছন্দ করতাম: process(Readable readThing, Writable writeThing)এবং যদি আপনার অবশ্যই এটি ব্যবহার করে প্রার্থনা করা হয় process(foo, foo)
জোচিম সৌর

1
সঠিক বাক্য গঠন নয় <RW extends Readable&Writable>?
থেকে

1
@ জোয়াচিমসৌয়ার: আপনি কেন এমন দৃষ্টিভঙ্গি পছন্দ করবেন যা কেবল দৃষ্টিভঙ্গিপূর্ণর চেয়ে সহজে ভেঙে যায়? যদি আমি কল প্রক্রিয়া (foo, বার) এবং foo এবং বার পৃথক হয়, পদ্ধতি ব্যর্থ হতে পারে।
মাইকেল শ

@ মিশেলশা: আমি যা বলছি তা হ'ল তারা যখন ভিন্ন ভিন্ন বস্তু হয় তখন এটি ব্যর্থ হয় না । এটা কেন করা উচিত? যদি এটি হয় তবে আমি যুক্তি দেব যা processএকাধিক বিভিন্ন কাজ করে এবং একক-দায়িত্ব নীতি লঙ্ঘন করে।
জোচিম সউর

@ জোছিমসৌয়ার: কেন এটি ব্যর্থ হবে না? (i = 0; j <100; i ++) এর জন্য (i = 0; i <100; i ++) এর মতো লুপটি কার্যকর নয়। লুপ উভয়ই একই ভেরিয়েবলটি পড়ে এবং লিখতে থাকে এবং এটি এসআরপি লঙ্ঘন করে না।
মাইকেল শ

12

যদি এমন কোনও জায়গা থাকে যেখানে আপনার myObjectউভয় হিসাবে প্রয়োজন হয় Readableএবং Writableআপনি করতে পারেন:

  • রিফ্যাক্টর place জায়গা? পড়া এবং লেখা দুটি আলাদা জিনিস। যদি কোনও পদ্ধতি উভয়ই করে, সম্ভবত এটি একক দায়িত্বের নীতি অনুসরণ করে না।

  • myObjectদু'বার পাস করুন , হিসাবে Readableএবং একটি হিসাবে Writable(দুটি যুক্তি)। পদ্ধতিটি একই জিনিস নয় বা না তা কী যত্ন করে?


1
আপনি যখন এটি একটি যুক্তি হিসাবে ব্যবহার করেন এটি কাজ করতে পারে এবং সেগুলি পৃথক উদ্বেগ। তবে কখনও কখনও আপনি সত্যিই একই সাথে পঠনযোগ্য এবং লেখার জন্য উপযুক্ত কোনও জিনিস চান (একই কারণে আপনি বাইটআরআউটপুট স্ট্রিম ব্যবহার করতে চান উদাহরণস্বরূপ)
nablex

কিভাবে? আউটপুট স্ট্রিমগুলি নাম হিসাবে ইঙ্গিত করে - এটি পড়তে পারে এমন ইনপুট স্ট্রিমগুলি। সি # তে একই - একটি StreamWriterবনাম StreamReader(এবং আরও অনেক)
কনরাড মোরাউস্কি

বাইটস পেতে (toByteArray ()) পেতে আপনি একটি বাইটআরআর আউটপুট স্ট্রিমে লিখুন। এটি + পঠিত লেখার সমতুল্য। ইন্টারফেসের পিছনে আসল কার্যকারিতা অনেকটা একই তবে আরও সাধারণ পদ্ধতিতে। কখনও কখনও আপনি কেবল পড়তে বা লিখতে চাইবেন, কখনও কখনও আপনি উভয়ই চাইবেন। আরেকটি উদাহরণ বাইটবফার।
nablex

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

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

4

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

যাইহোক, আমি যে মডিউলটিতে কাজ করছি তার প্রায় শেষ করেছি এবং বর্তমানে আমি মোড়কের ইন্টারফেসের জন্য বেছে নিয়েছি:

interface Container extends Readable, Writable {}

এখন আপনি কমপক্ষে করতে পারেন:

Container container = IOUtils.newContainer();
container.write("something".getBytes());
System.out.println(IOUtils.toString(container));

আমার নিজের ধারকটির বাস্তবায়ন (বর্তমানে 3) সমস্ত পৃথক ইন্টারফেসের বিপরীতে কনটেইনার প্রয়োগ করে তবে কোনও প্রয়োগে এটি ভুলে যাওয়া উচিত, আইইউটিস একটি ইউটিলিটি পদ্ধতি প্রদান করে:

Readable myReadable = ...;
// assuming myReadable is also Writable you can do this:
Container container = IOUtils.toByteContainer(myReadable);

আমি জানি এটি সর্বোত্তম সমাধান নয় তবে এই মুহূর্তে এটি এখনও সবচেয়ে ভাল উপায় কারণ পাত্রে এখনও মোটামুটি বড় ইউজকেস case


1
আমি মনে করি এটি একেবারে ঠিক আছে। অন্যান্য উত্তরে প্রস্তাবিত অন্যান্য পদ্ধতির কয়েকটি থেকে ভাল।
টম অ্যান্ডারসন

0

একটি জেনেরিক মাইবজেক্ট উদাহরণ দেওয়া হয়েছে, আপনি সর্বদা এটি জানতে বা পড়াতে সমর্থন করে কিনা তা জানা দরকার। সুতরাং আপনার কোড যেমন হবে:

if (myObject instanceof Readable)  {
    Readable  r = (Readable) myObject;
    readThisReadable( r );
}

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

সুতরাং আমি সম্ভবত এটি সঙ্গে যেতে হবে:

interface TheWholeShabam  {
    public boolean  isReadable();
    public boolean  isWriteable();
    public void     read();
    public void     write();
}

এটি readThisReadableএখন প্যারামিটার হিসাবে গ্রহণ করা, readThisWholeShabamযে কোনও ক্লাস পরিচালনা করতে পারে যা কেবলমাত্র মাইবজেক্ট নয়, থিওহোলশ্যাবাম প্রয়োগ করে। এবং এটি লিখতে সক্ষম হলে এটি লিখতে পারে এবং যদি তা না হয় তবে এটি লিখতে পারে। (আমরা আসল "বহুবিজ্ঞান" পেয়েছি))

সুতরাং কোডের প্রথম সেটটি হয়ে যায়:

TheWholeShabam  myObject = ...;
if (myObject.isReadable()
    readThisWholeShebam( myObject );

এবং আপনি এখানে পাঠানোর মাধ্যমে এখানে একটি লাইন সংরক্ষণ করতে পারেন এই হোয়াটসাহেবাম () পাঠযোগ্যতা পরীক্ষা করে দেখুন।

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

অন্য একটি জিনিস: আপনি যদি কোনও ক্লাসে () পড়ার জন্য কল এবং যে ক্লাসে কোনও কিছু ট্র্যাশ না করে লেখেন না () লেখার জন্য কলটি পরিচালনা করতে পারেন, আপনি isreedable () এবং isWritable এড়িয়ে যেতে পারেন () পদ্ধতি। এটি পরিচালনা করার জন্য এটি সবচেয়ে মার্জিত উপায় হবে - যদি এটি কাজ করে।

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