জাভাতে একাধিক জেনেরিক ইন্টারফেস প্রয়োগ করা


10

আমার একটি ইন্টারফেস দরকার যা আমাকে নির্দিষ্ট একটি স্বাক্ষর সহ একটি নির্দিষ্ট পদ্ধতির আশ্বাস দেয় is আমার কাছে যা আছে তার এখন পর্যন্ত:

public interface Mappable<M> {
    M mapTo(M mappableEntity);
}

সমস্যাটি দেখা দেয় যখন কোনও শ্রেণিটি অন্য একাধিক সত্তায় ম্যাপযোগ্য হয়। আদর্শ ক্ষেত্রে এটি হবে (জাভা নয়):

public class Something implements Mappable<A>, Mappable<B> {
    public A mapTo(A someObject) {...}
    public B mapTo(B someOtherObject) {...}
}

সম্ভব হিসাবে "জেনেরিক" হিসাবে এই অবশিষ্টটি অর্জন করার সর্বোত্তম উপায় কী হবে?

উত্তর:


10

এটি অবশ্যই টাইপ ইরেজরের কারণে আপনি করতে পারেন এমন কিছু নয় । রানটাইমের সময় আপনার দুটি পদ্ধতি রয়েছে public Object mapTo(Object)যা স্পষ্টতই সহাবস্থান করতে পারে না।

দুর্ভাগ্যক্রমে, আপনি যা করার চেষ্টা করছেন তা জাভা টাইপ সিস্টেমের বাইরে।

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

তবে আমি @ জোয়াকিমের উত্তরের দিকেও ইঙ্গিত করব, এটি এমন একটি ঘটনা হতে পারে যেখানে আপনি আচরণটিকে আলাদা আলাদা উপাদানগুলিতে বিভক্ত করতে এবং পুরো বিষয়টিটিকে পাশ কাটাতে পারেন।


3

যেমনটি আপনি দেখেছেন, আপনি বিভিন্ন ধরণের পরামিতিগুলির সাথে একই ইন্টারফেস দু'বার প্রয়োগ করতে পারবেন না (ক্ষয়ের কারণে: রানটাইম এ তারা একই ইন্টারফেস)।

এছাড়াও, এই পদ্ধতির একক দায়িত্বের নীতিকে লঙ্ঘন করা হয়েছে: আপনার শ্রেণীর উচিত একটি হওয়ার Something(যার অর্থ যাই হোক না কেন) হওয়ার দিকে মনোনিবেশ করা উচিত এবং সেই কাজটিতে ম্যাপিং Aবা B সংযোজন করা উচিত নয় ।

মনে হচ্ছে আপনার সত্যিই একটি Mapper<Something,A>এবং একটি হওয়া উচিত Mapper<Something,B>। এইভাবে প্রতিটি শ্রেণীর একটি একক স্পষ্টভাবে সংজ্ঞায়িত দায়িত্ব থাকে এবং আপনি একই ইন্টারফেসটি দু'বার প্রয়োগ করার সমস্যায় পড়েন না।


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

@ ইস্তানী: হ্যাঁ, এগুলি কিছুটা দৃly়ভাবে মিলিত হয়েছে তবে তাদের পৃথক দায়িত্ব রয়েছে। এ সম্পর্কেও চিন্তা করুন: যখন আপনি একটি নতুন শ্রেণি চালু করেন Cএবং Somethingআপনি সেটির জন্য ম্যাপেবল হতে চান , তখন আপনাকে সংশোধন করতে হবে Somethingযা খুব বেশি মিলিত। কেবল একটি নতুন যুক্ত SoemthingToCMapperকরা কম অনুপ্রবেশকারী।
জোছিম সউর

1
এটির জন্য +1 - আপনি যদি ওপি যা চান তা অর্জন করার চেষ্টা করছেন তবে (জাভাতে) আপনি সাধারণত উত্তরাধিকারের তুলনায় রচনাটিকে সমর্থন করবেন। ডিফল্ট পদ্ধতি সহ জাভা 8 এটিকে আরও সহজ করে তোলে - তবে প্রত্যেকে এখনও রক্তপাতের প্রান্তে লাফিয়ে উঠতে পারে না :-)।
মার্টিজ ভার্বার্গ

0

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

// Mappable.java
public interface Mappable<M> {
    M mapTo(M mappableEntity);
}

// TwoMappables.java
public interface TwoMappables {
    default Mappable<A> mapableA() {
         return new MappableA();
    }

    default Mappable<B> mapableB() {
         return new MappableB();
    }

    class MappableA implements Mappable<A> {}
    class MappableB implements Mappable<B> {}
}

// Something.java
public class Something implements TwoMappables {
    // ... business logic ...
    mapableA().mapTo(A);
    mapableB().mapTo(B);
}

আরও তথ্যের জন্য এবং আরও উদাহরণের জন্য দয়া করে এখানে দেখুন: একটি জাভা ক্লাস কীভাবে তৈরি করতে হবে যা দুটি জেনেরিক ধরণের সাথে একটি ইন্টারফেস প্রয়োগ করে?


-1
public interface IMappable<S, T> {
    T MapFrom(S source);
}

// T - target
// S - source

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

জোছিমকে খুশি রাখতে আপডেট করুন

public interface ITypeConverter<TSource, TDestination>
{
    TDestination Convert(TSource source);
}

তবে এখন আমরা অটোমেপার রিয়েল-এ রয়েছি ( http://automapper.codeplex.com/wikipage?title=Custom%20Type%2020ververters )


আমি মনে করি না যে IMappableএমন কিছুর জন্য একটি ভাল নাম যা অন্য জিনিসগুলিকে মানচিত্র করে। Mapper(বা IMapper, যদি আপনার অবশ্যই ;-)) সম্ভবত আরও সঠিক। (যাইহোক, না, এটি আমার ডাউনভোট ছিল না)
জোছিম সউর

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

1
দুঃখিত, তবে আমার মতে কেউ আসলেই কোনও ডিজাইন সমস্যার "সমাধান" করতে এবং নামকরণকে উপেক্ষা করতে পারে না। ডিজাইন মানে বোঝা কাঠামো। ভুল নামকরণ বোঝার ক্ষেত্রে সমস্যা।
জোচিম সৌর

আপডেটে আপনার মনকে বিশ্রামে রাখা উচিত ;-)
কোডার্ট

1
@ কোডার্ট যদি আমি আপনার উত্তরটি সঠিকভাবে বুঝতে পারি তবে এটি "ম্যাপফ্রম" বোঝায় (যা নিম্নতর হওয়া উচিত ;-) অবজেক্টটি তৈরি করে। আমার ক্ষেত্রে এটি কেবল ইতিমধ্যে তৈরি করা কোনও বস্তুর তথ্য পূরণ করছে।
এস্তানি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.