রুবিতে জাভা ইন্টারফেস সমতুল্য কী?


106

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

একটি উপায় হ'ল উত্তরাধিকার এবং পদ্ধতি_মিজিং ব্যবহার করে তা অর্জন করতে পারে তবে কি আরও কোনও উপযুক্ত পন্থা পাওয়া যায়?



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

4
এই প্রশ্নটি [ রুবিতে, সি # তে একটি ইন্টারফেসের সমতুল্য কী? ] ( স্ট্যাকওভারফ্লো.কম / কিউ / 3505521 / #3507460 )।
Jörg ডব্লু মিটাগ

4
আমার কেন এটি দরকার? আপনি "সংস্করণযোগ্য" হিসাবে কল করতে পারেন এমন কিছু বাস্তবায়ন করতে চাই যা নথি / ফাইলগুলিকে সংস্করণযোগ্য তবে কী ব্যবহার করে সংস্করণযোগ্য করে তোলে .... উদাহরণস্বরূপ আমি এসভিএন বা সিভিএসের মতো বিদ্যমান সংগ্রহস্থল সফ্টওয়্যারগুলি ব্যবহার করে এটি সংস্করণযোগ্য করতে পারি। আমি যেই আনারিলিং মেকানিজমটি বেছে নিই না কেন তার কয়েকটি প্রাথমিক ন্যূনতম ফাংশন সরবরাহ করা উচিত। আমি কোনও নতুন অন্তর্নিহিত সংগ্রহস্থল প্রয়োগের মাধ্যমে এই ন্যূনতম নূন্যতম ফাংশনগুলির বাস্তবায়ন কার্যকর করতে আইটেমের মতো ইন্টারফেস ব্যবহার করতে চাই।
ক্রেজিক্রভ

তার POODR বইয়ের স্যান্ডি মেটজ ইন্টারফেস ডকুমেন্ট করতে পরীক্ষা ব্যবহার করে। এই বইটি পড়া সত্যিই মূল্যবান। ২০১৫ সাল পর্যন্ত আমি বলব যে @ অ্যালেক্সান্ডার-পোহল উত্তরটি সবচেয়ে ভাল।
গ্রেগ ড্যান

উত্তর:


85

অন্য কোনও ভাষার মতো রুবির ইন্টারফেস রয়েছে ।

নোট করুন যে আপনাকে ইন্টারফেসের ধারণার সাথে সংঘাত না দেওয়ার বিষয়ে সতর্ক থাকতে হবে , যা interfaceজাভা, সি # এবং ভিবি.এনইটি প্রোগ্রামিংয়ের মূলশব্দ যা ধারণার সাথে একটি ইউনিটের দায়িত্ব, গ্যারান্টি এবং প্রোটোকলের একটি বিমূর্ত স্পেসিফিকেশন is ভাষা। রুবিতে আমরা প্রাক্তনটিকে সর্বদা ব্যবহার করি তবে পরবর্তীকালের সহজলভ্যতা নেই।

এই দুটি পার্থক্য করা খুব গুরুত্বপূর্ণ। কী গুরুত্বপূর্ণ ইন্টারফেস , না interfaceinterfaceআপনি উপযোগী প্রায় কাছাকাছি কিছুই বলে। জাভাতে চিহ্নিতকারী ইন্টারফেসগুলির চেয়ে ভাল এটি আর কিছুই প্রদর্শন করে না, যা ইন্টারফেসগুলি যার কোনও সদস্যই নেই: কেবল একবার দেখুন java.io.Serializableএবং java.lang.Cloneable; এই দুটি interfaceগুলি খুব আলাদা জিনিস বোঝায় , তবুও তাদের ঠিক একই স্বাক্ষর রয়েছে।

সুতরাং, দুই যদি interfaceগুলি মানে ভিন্ন জিনিস, একই স্বাক্ষর আছে, কি ঠিক হল interfaceএমনকি আপনি নিশ্চয়তা?

আর একটি ভাল উদাহরণ:

package java.util;

interface List<E> implements Collection<E>, Iterable<E> {
    void add(int index, E element)
        throws UnsupportedOperationException, ClassCastException,
            NullPointerException, IllegalArgumentException,
            IndexOutOfBoundsException;
}

কি ইন্টারফেস এর java.util.List<E>.add?

  • সংগ্রহের দৈর্ঘ্য হ্রাস না করে
  • সংগ্রহের আগে থাকা সমস্ত আইটেমগুলি এখনও আছে
  • যে elementসংগ্রহে আছে

এবং এর মধ্যে আসলে কোনটি দেখা যাচ্ছে interface? কেউই না! এর মধ্যে এমন কিছু নেই interfaceযা বলছে যে Addপদ্ধতিটি অবশ্যই একেবারে যুক্ত করতে পারে, এটি সংগ্রহ থেকে কোনও উপাদান সরাতে পারে ।

এটি এর পুরোপুরি বৈধ বাস্তবায়ন interface:

class MyCollection<E> implements java.util.List<E> {
    void add(int index, E element)
        throws UnsupportedOperationException, ClassCastException,
            NullPointerException, IllegalArgumentException,
            IndexOutOfBoundsException {
        remove(element);
    }
}

আরেকটি উদাহরণ: java.util.Set<E>এটি আসলে কোথায় বলে যে এটি, এটি আপনি জানেন, একটি সেট ? কোথাও! বা আরও স্পষ্টভাবে ডকুমেন্টেশনে। ইংরেজীতে.

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

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

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

এছাড়াও, জাভা-র মতো, স্বীকৃতি টেস্টগুলি ইন্টারফেসগুলিও নির্দিষ্ট করতে ব্যবহৃত হতে পারে ।

বিশেষ করে, রুবি এ, ইন্টারফেস একটি বস্তুর এটা করতে পারি দ্বারা নির্ধারিত হয় না , কি না classহয়, বা কি moduleএটি দ্রবণ। একটি যে কোনো বস্তু <<পদ্ধতি যোগ করা যেতে পারে। এই ইউনিট পরীক্ষা, যেখানে আপনি কেবল একটি মধ্যে পাস করতে পারেন খুবই দরকারী Arrayবা Stringএকটি আরো জটিল পরিবর্তে Logger, যদিও Arrayএবং Loggerএকটি সুনির্দিষ্ট ভাগ করি না interfaceআসলে তারা উভয় একটি পদ্ধতি বলা আছে ছাড়া <<

আরেকটি উদাহরণ হল StringIO, যা কার্যকরী একই ইন্টারফেস হিসাবে IOএবং এইভাবে একটি বৃহৎ অংশ ইন্টারফেস এর File, কিন্তু ব্যতীত কোন সাধারণ পূর্বপুরুষ ভাগ না করে Object


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

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

9
স্ট্র্যাটিচ্যালি টাইপ করা একক-উত্তরাধিকারের ভাষায় (যেমন ট্রিট এবং উভয় হিসাবে ) বিভিন্ন ধরণের একইরূপে চিকিত্সা করার জন্য এই interface কনস্ট্রাক্টটির প্রয়োজন কেবল , এই উত্তরটি দেখায় ইন্টারফেসের সাথে এটির তেমন কিছুই করার নেই । রুবি স্ট্যাটিকালি টাইপ করা হয়নি তাই কনস্ট্রাক্টের দরকার নেই । LinkedHashSetArrayListCollection
ইসাইলিজা

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

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

61

আরএসপেকের "ভাগ করা উদাহরণ" চেষ্টা করে দেখুন:

https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/example-groups/shared- উদাহরণ

আপনি আপনার ইন্টারফেসের জন্য একটি নির্দিষ্ট বিবরণ লিখুন এবং তারপরে প্রতিটি প্রয়োগকারীর বৈশিষ্ট্যে একটি লাইন রাখুন, যেমন।

it_behaves_like "my interface"

সম্পূর্ণ উদাহরণ:

RSpec.shared_examples "a collection" do
  describe "#size" do
    it "returns number of elements" do
      collection = described_class.new([7, 2, 4])
      expect(collection.size).to eq(3)
    end
  end
end

RSpec.describe Array do
  it_behaves_like "a collection"
end

RSpec.describe Set do
  it_behaves_like "a collection"
end

আপডেট : আট বছর পরে (2020) রুবিতে এখন শরবতের মাধ্যমে স্ট্যাটিক্যালি টাইপযুক্ত ইন্টারফেসের জন্য সমর্থন রয়েছে। শরবত ডক্সে অ্যাবস্ট্রাক্ট ক্লাস এবং ইন্টারফেসগুলি দেখুন ।


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

4
আমি সম্মত, এই উত্তরটি আমাকে জাভা বিকাশকারী হিসাবে উপরের স্বীকৃত উত্তরের চেয়ে রুবিতে চলে যেতে অনেক বেশি সহায়তা করেছে।
ক্যাম

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

রুবি সবকিছুকে ব্যবহারিক করে তোলে। আপনি যদি নথিভুক্ত এবং ভাল লিখিত কোড রাখতে চান তবে পরীক্ষা / স্পেস যুক্ত করুন এবং এটি স্ট্যাটিক টাইপিং চেকের মতো হবে।
দিমিত্রি Polushkin

42

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

রুবির সেই কার্যকারিতা নেই। নীতিগতভাবে, এগুলির দরকার নেই কারণ রুবি হাঁসের টাইপিং বলে যা এটি ব্যবহার করে

আপনি নিতে পারেন এমন কয়েকটি পন্থা রয়েছে।

ব্যতিক্রম উত্থাপন যা বাস্তবায়ন লিখুন; যদি একটি সাবক্লাস অব্যক্ত পদ্ধতি ব্যবহার করার চেষ্টা করে তবে এটি ব্যর্থ হবে

class CollectionInterface
  def add(something)
    raise 'not implemented'
  end
end

উপরের পাশাপাশি, আপনার টেস্টিং কোডটি লিখতে হবে যা আপনার চুক্তিগুলি কার্যকর করে (এখানে অন্য পোস্টে কী ভুলভাবে ইন্টারফেস কল করে )

যদি আপনি নিজেকে সব সময়ের মতো অকার্যকর পদ্ধতিগুলি লেখার মতো দেখতে পান তবে একটি সহায়ক মডিউল লিখুন যা এটি ক্যাপচার করে

module Interface
  def method(name)
    define_method(name) { |*args|
      raise "interface method #{name} not implemented"
    }
  end
end

class Collection
  extend Interface
  method :add
  method :remove
end

এখন, উপরের রুবি মডিউলগুলির সাথে একত্রিত করুন এবং আপনি যা চান তার কাছাকাছি ...

module Interface
  def method(name)
    define_method(name) { |*args|
      raise "interface method #{name} not implemented"
    }
  end
end

module Collection
  extend Interface
  method :add
  method :remove
end

col = Collection.new # <-- fails, as it should

এবং তারপর আপনি করতে পারেন

class MyCollection
  include Collection

  def add(thing)
    puts "Adding #{thing}"
  end
end

c1 = MyCollection.new
c1.add(1)     # <-- output 'Adding 1'
c1.remove(1)  # <-- fails with not implemented

আমাকে আরও একবার জোর দেওয়া যাক: এটি একটি প্রাথমিক বিষয়, যেমন রুবির সবকিছু রানটাইমের সময় ঘটে; কোন কম্পাইল সময় চেক আছে। যদি আপনি এটি পরীক্ষার মাধ্যমে দম্পতি করেন তবে আপনার ত্রুটিগুলি তুলতে সক্ষম হওয়া উচিত। এরপরেও, আপনি যদি উপরেরটি আরও গ্রহণ করেন তবে আপনি সম্ভবত এমন একটি ইন্টারফেস লিখতে সক্ষম হবেন যা প্রথম শ্রেণীর কোনও বস্তু তৈরি হওয়ার পরে ক্লাসে পরীক্ষা করে; আপনার পরীক্ষাগুলি কল করার মতো সহজ করে তুলছে MyCollection.new... হ্যাঁ, উপরে থেকে :)


ঠিক আছে তবে যদি আপনার সংগ্রহ = আমার সংগ্রহটি কোনও ইন্টারফেসে সংজ্ঞায়িত কোনও পদ্ধতি প্রয়োগ করে তবে এটি পুরোপুরি কার্যকর হয় না, তাই আপনি নিশ্চিত করতে পারবেন না যে আপনার অবজেক্টটিতে কেবল ইন্টারফেসের পদ্ধতিগুলির সংজ্ঞা রয়েছে।
জোয়েল আজমের

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

10

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

class Object
  def interface(method_hash)
    obj = new
    method_hash.each do |k,v|
      if !obj.respond_to?(k) || !((instance_method(k).arity+1)*-1)
        raise NotImplementedError, "#{obj.class} must implement the method #{k} receiving #{v} parameters"
      end
    end
  end
end

class Person
  def work(one,two,three)
    one + two + three
  end

  def sleep
  end

  interface({:work => 3, :sleep => 0})
end

ব্যক্তির উপর ঘোষিত পদ্ধতিগুলির একটি অপসারণ বা যুক্তিগুলির সংখ্যা পরিবর্তন করে এ NotImplementedError


5

জাভা উপায়ে ইন্টারফেসের মতো জিনিস নেই। তবে রুবিতে আপনি অন্যান্য জিনিস উপভোগ করতে পারেন।

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

উল্লিখিত যোগাযোগগুলি লাইভ প্রকল্প নয়, যদিও লক্ষ্যটি প্রথমে দুর্দান্ত বলে মনে হচ্ছে, মনে হয় বেশিরভাগ রুবি বিকাশকারী কঠোর প্রকারের পরীক্ষা ছাড়াই বাঁচতে পারবেন। তবে রুবির নমনীয়তা প্রকারের চেকিং প্রয়োগ করতে সক্ষম করে।

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

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


সেই ডেভ টমাস লেকচারের পে-ওলের পিছনে রয়েছে।
Purplejacket

5

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

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

আপনি যদি রুবির ইন্টারফেসের সাথে সত্যিই উদ্বিগ্ন হন তবে আমি এমন একটি টেস্টিং ফ্রেমওয়ার্ক ব্যবহার করার পরামর্শ দেব যা চুক্তি পরীক্ষার প্রয়োগ করে।


3

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

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

class FooInterface
  class NotDefinedMethod < StandardError; end
  REQUIRED_METHODS = %i(foo).freeze
  def initialize(object)
    @object = object
    ensure_method_are_defined!
  end
  def method_missing(method, *args, &block)
    ensure_asking_for_defined_method!(method)
    @object.public_send(method, *args, &block)
  end
  private
  def ensure_method_are_defined!
    REQUIRED_METHODS.each do |method|
      if !@object.respond_to?(method)
        raise NotImplementedError, "#{@object.class} must implement the method #{method}"
      end
    end
  end
  def ensure_asking_for_defined_method!(method)
    unless REQUIRED_METHODS.include?(method)
      raise NotDefinedMethod, "#{method} doesn't belong to Interface definition"
    end
  end
end

তারপরে আপনি কমপক্ষে ইন্টারফেস চুক্তি দিয়ে কোনও অবজেক্ট লিখতে পারেন:

class FooImplementation
  def foo
    puts('foo')
  end
  def bar
    puts('bar')
  end
end

আপনি ইন্টারফেসের মাধ্যমে যা ঠিকভাবে সংজ্ঞায়িত করেছেন তা নিশ্চিত করার জন্য আপনি নিজের বস্তুকে নিরাপদে কল করতে পারেন can

#  > FooInterface.new(FooImplementation.new).foo
# => foo

#  > FooInterface.new(FooImplementation.new).bar
# => FooInterface::NotDefinedMethod: bar doesn't belong to Interface definition

এবং আপনি পাশাপাশি নিশ্চিত করতে পারেন যে আপনার অবজেক্টটি আপনার সমস্ত ইন্টারফেস পদ্ধতির সংজ্ঞাটি কার্যকর করে

class BadFooImplementation
end

#  > FooInterface.new(BadFooImplementation.new)
# => NotImplementedError: BadFooImplementation must implement the method foo

2

আমার অতিরিক্ত প্রয়োজনের জন্য আমি কার্লোসিয়ামের জবাবটি কিছুটা বাড়িয়ে দিয়েছি। এটি ইন্টারফেস শ্রেণিতে কয়েকটি অতিরিক্ত প্রয়োগ এবং বিকল্প যুক্ত করে: required_variableএবং optional_variableএটি একটি ডিফল্ট মান সমর্থন করে।

আমি নিশ্চিত নই যে আপনি এই মেটা প্রোগ্রামিংটি খুব বড় কিছু দিয়ে ব্যবহার করতে চাইবেন।

অন্যান্য উত্তর যেমন বলেছে, আপনি পরীক্ষা নিখরচায় যা আপনি যা খুঁজছেন তা যথাযথভাবে প্রয়োগ করে, বিশেষত একবার আপনি প্যারামিটারগুলি প্রয়োগ করতে এবং মানগুলি ফেরত দিতে চান want

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

কোড উদাহরণ

ইন্টারফেস.আরবি

module Interface
  def method(name)
    define_method(name) do
      raise "Interface method #{name} not implemented"
    end
  end

  def required_variable(name)
    define_method(name) do
      sub_class_var = instance_variable_get("@#{name}")
      throw "@#{name} must be defined" unless sub_class_var
      sub_class_var
    end
  end

  def optional_variable(name, default)
    define_method(name) do
      instance_variable_get("@#{name}") || default
    end
  end
end

প্লাগইন.আরবি

আমি প্রদত্ত প্যাটার্নটির জন্য আমি সিঙ্গলটন লাইব্রেরিটি ব্যবহার করছি। এই "ইন্টারফেস" প্রয়োগ করার সময় কোনও উপশ্রেণী এককভাবে লাইব্রেরি লাইব্রেরি পায়।

require 'singleton'

class Plugin
  include Singleton

  class << self
    extend Interface

    required_variable(:name)
    required_variable(:description)
    optional_variable(:safe, false)
    optional_variable(:dependencies, [])

    method :run
  end
end

my_plugin.rb

আমার প্রয়োজনের জন্য এটি প্রয়োজন হয় শ্রেণিটি "ইন্টারফেস" প্রয়োগ করে এটি সাবক্লাস করে।

class MyPlugin < Plugin

  @name = 'My Plugin'
  @description = 'I am a plugin'
  @safe = true

  def self.run
    puts 'Do Stuff™'
  end
end

2

রুবি নিজেই জাভাতে ইন্টারফেসের সঠিক সমতুল্য নয়।

তবে, যেহেতু এই জাতীয় ইন্টারফেসটি মাঝে মাঝে খুব দরকারী হতে পারে, তাই আমি নিজের জন্য রুবির জন্য একটি রত্ন তৈরি করেছি, যা জাভা ইন্টারফেসকে খুব সাধারণ উপায়ে ইমুলেট করে।

এটি বলা হয় class_interface

এটি বেশ সহজভাবে কাজ করে। প্রথমে রত্নটি ইনস্টল করুন gem install class_interfaceবা এটিকে আপনার গেমফিল এবং রুন্ডে যুক্ত করুন bundle install

একটি ইন্টারফেস সংজ্ঞায়িত:

require 'class_interface'

class IExample
  MIN_AGE = Integer
  DEFAULT_ENV = String
  SOME_CONSTANT = nil

  def self.some_static_method
  end

  def some_instance_method
  end
end

যে ইন্টারফেস বাস্তবায়ন:

class MyImplementation
  MIN_AGE = 21
  DEFAULT_ENV = 'dev' 
  SOME_CONSTANT = 'some_value'

  def specific_method
    puts "very specific"
  end

  def self.some_static_method
    puts "static method is implemented!"
  end

  def some_instance_method
    # implementation
  end

  def self.another_methods
    # implementation
  end

  implements IExample
end

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

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

আরও at: https://github.com/magynhard/class_interface


0

আমি বুঝতে পেরেছি যে আমি একটি নির্দিষ্ট আচরণ চাই যে জিনিসগুলিতে সুরক্ষা চেক করার জন্য আমি "প্রয়োগিত ত্রুটি নয়" প্যাটার্নটি খুব বেশি ব্যবহার করছি। মূলত এই জাতীয় ইন্টারফেস ব্যবহার করতে দেয় এমন এক রত্ন লেখার সমাপ্তি:

require 'playable' 

class Instrument 
  implements Playable
end

Instrument.new #will throw: Interface::Error::NotImplementedError: Expected Instrument to implement play for interface Playable

এটি পদ্ধতির আর্গুমেন্টগুলির জন্য পরীক্ষা করে না । এটি সংস্করণ হিসাবে না 0.2.0Https://github.com/bluegod/ মুদ্রণে আরও বিশদ উদাহরণ

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