পিআইএমপিএল প্যাটার্নটির বিন্দু কী, যখন আমরা সি ++ তে একই উদ্দেশ্যে ইন্টারফেস ব্যবহার করতে পারি?


49

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

তবে সি ++ তে ইন্টারফেস / খাঁটি-বিমূর্ত ক্লাসগুলিরও এই ক্ষমতা রয়েছে, এগুলি ডেটা / প্রকার / বাস্তবায়ন আড়াল করতেও ব্যবহার করা যেতে পারে। এবং কোনও বস্তু তৈরি করার সময় কলারকে কেবল ইন্টারফেসটি দেখতে দেয়, আমরা ইন্টারফেসের শিরোনামে একটি কারখানা পদ্ধতি ঘোষণা করতে পারি।

তুলনাটি হ'ল:

  1. ব্যয় :

    ইন্টারফেস উপায়ের ব্যয় কম, কারণ আপনার এমনকি পাবলিক রেপার ফাংশন বাস্তবায়নের পুনরাবৃত্তি করার void Bar::doWork() { return m_impl->doWork(); }প্রয়োজন নেই, আপনাকে কেবল ইন্টারফেসে স্বাক্ষরটি সংজ্ঞায়িত করতে হবে।

  2. ভালভাবে বোঝা :

    ইন্টারফেস প্রযুক্তি প্রতিটি সি ++ বিকাশকারী দ্বারা আরও ভাল বোঝা যায়।

  3. পারফরম্যান্স :

    ইন্টারফেস ওয়ে কর্মক্ষমতা PImpl আইডিয়ামের চেয়ে খারাপ নয়, উভয়ই অতিরিক্ত মেমরি অ্যাক্সেস। আমি ধরে নিই পারফরম্যান্স একই রকম।

আমার প্রশ্নটি বর্ণনা করার জন্য সিউডোকোডটি নীচে দেওয়া হয়েছে:

// Forward declaration can help you avoid include BarImpl header, and those included in BarImpl header.
class BarImpl;
class Bar
{
public:
    // public functions
    void doWork();
private:
    // You don't need to compile Bar.cpp after changing the implementation in BarImpl.cpp
    BarImpl* m_impl;
};

একই উদ্দেশ্য ইন্টারফেস ব্যবহার করে প্রয়োগ করা যেতে পারে:

// Bar.h
class IBar
{
public:
    virtual ~IBar(){}
    // public functions
    virtual void doWork() = 0;
};

// to only expose the interface instead of class name to caller
IBar* createObject();

সুতরাং পিআইএমপিএল এর পয়েন্ট কি?

উত্তর:


50

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

পিপল ব্যবহারের তিনটি কারণ রয়েছে:

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

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

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

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

  1. নন-ভার্চুয়াল পদ্ধতি যুক্ত করা এবিআইকে ভেঙে দেয় না, তবে ভার্চুয়ালটি যুক্ত করে। ইন্টারফেসগুলি অতএব পদ্ধতি যুক্ত করার অনুমতি দেয় না, পিআইএমপিএল করে।

  2. ইন্টারফেসটি কেবল পয়েন্টার / রেফারেন্সের মাধ্যমেই ব্যবহার করা যায়, তাই ব্যবহারকারীকে যথাযথ সংস্থান পরিচালনার যত্ন নিতে হবে। অন্যদিকে পিআইএমপিএল ব্যবহার করে ক্লাসগুলি এখনও মান ধরণের এবং অভ্যন্তরীণভাবে সংস্থানগুলি পরিচালনা করে।

  3. লুকানো বাস্তবায়ন উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে না, পিআইএমপিএল সহ ক্লাস পারে।

এবং অবশ্যই ইন্টারফেস ব্যতিক্রম সুরক্ষায় সাহায্য করবে না। এর জন্য আপনার ক্লাসের ভিতরে ইন্ডিয়ারেশন দরকার।


ভাল যুক্তি. Implক্লাসে পাবলিক ফাংশন যুক্ত করলে তা ভাঙবে না ABI, তবে ইন্টারফেসে পাবলিক ফাংশন যুক্ত হবে ABI
ZijingWu

1
একটি ফাংশনে / পদ্ধতি যোগ করার পদ্ধতি নেই আছে ABI- র বিরতি; কঠোরভাবে অ্যাডিটিভ পরিবর্তনগুলি পরিবর্তন ভাঙ্গছে না। যাইহোক, আপনি কখনও তাই যত্নবান হতে হবে; ফ্রন্ট-এন্ড এবং ব্যাক-এন্ডের মধ্যস্থতাকারী কোডটি সংস্করণ সহ সমস্ত ধরণের মজাদার সাথে মোকাবেলা করতে হবে। এটি সব জটিল হয়ে ওঠে gets (এই ধরণের জিনিসটির কারণেই বেশ কয়েকটি সফ্টওয়্যার প্রকল্প সি থেকে সি +++ পছন্দ করে; এটি এবিআই ঠিক কী তার উপর আরও কঠোর گرفت পেতে দেয়))
ডোনাল ফেলো

3
@ ডোনালফেলোস: একটি সর্বজনীন অনুষ্ঠান / পদ্ধতি যুক্ত করা এবিআইকে ভেঙে দেয় নাভার্চুয়াল পদ্ধতি যুক্ত করা সর্বদা এমনটি করে এবং না করে যদি না ব্যবহারকারীকে বস্তুর উত্তরাধিকারী হওয়া থেকে বিরত রাখা হয় (যা পিআইএমপিএল অর্জন করে)।
জান হুডেক

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

1
পিআইএমপিএল প্রাথমিক সংকলনের সময়ও হ্রাস করে। উদাহরণ হিসেবে বলা যায়, আমার বাস্তবায়নের কিছু টেমপ্লেট ধরনের একটি ক্ষেত্র হয়েছে থাকে (যেমন unordered_set), PImpl ছাড়া, আমি প্রয়োজন #include <unordered_set>মধ্যে MyClass.h। PImpl, আমি শুধুমাত্র এটা অন্তর্ভুক্ত করতে হবে .cppফাইল, না .hফাইল, এবং সেইজন্য অন্য সব কিছুর এটি অন্তর্ভুক্ত ...
মার্টিন সি মার্টিন

7

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

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


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

আপনি যদি লিংক-টাইম অপ্টিমাইজেশন ব্যবহার করেন তবে এটি কেবল সত্য। পিআইএমপিএলের বিষয়টি হ'ল সংকলকটির বাস্তবায়ন নেই, এমনকি ফরওয়ার্ডিংয়েরও নয়। লিঙ্কার যদিও।
মার্টিন সি মার্টিন

5

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

  1. শ্রেণীর ব্যক্তিগত সদস্য ভেরিয়েবলগুলি পরিবর্তন করতে তার উপর নির্ভরশীল ক্লাসগুলির পুনরায় সংক্রামনের প্রয়োজন হয় না, ফলে সময়গুলি দ্রুত হয় এবং ফ্রেজিবাইনারিআইন্টারফেসপ্রোব্লম হ্রাস হয়।
  2. শিরোনাম ফাইলটি # ব্যক্তিগত ক্লায়েন্টগুলিতে ব্যক্তিগত মান ভেরিয়েবলগুলিতে 'মান দ্বারা' ব্যবহৃত হয় এমন ক্লাসগুলি অন্তর্ভুক্ত করার প্রয়োজন হয় না, সুতরাং সংকলনের সময়গুলি দ্রুততর হয়।

পিম্পল আইডিয়াম একটি সংকলন-সময় অপ্টিমাইজেশন, একটি নির্ভরতা ভাঙার কৌশল। এটি বড় হেডার ফাইলগুলি কেটে দেয়। এটি আপনার শিরোনামকে কেবল সর্বজনীন ইন্টারফেসে হ্রাস করে। আপনি যখন এটি কীভাবে কাজ করে সে সম্পর্কে ভাবেন যখন শিরোনামের দৈর্ঘ্য সি ++ তে গুরুত্বপূর্ণ। # অন্তর্ভুক্ত কার্যকরভাবে উত্স ফাইলটিতে শিরোলেখ ফাইলটিকে সম্মতিযুক্ত করে - তাই প্রাক প্রক্রিয়াজাত সি ++ ইউনিটগুলির পরে মনে রাখবেন খুব বড় হতে পারে। পিম্পল ব্যবহার করে সংকলনের সময়গুলি উন্নতি করতে পারে।

অন্যান্য আরও ভাল নির্ভরশীলতা ব্রেকিং কৌশল রয়েছে - এতে আপনার নকশাটি উন্নত করা জড়িত। ব্যক্তিগত পদ্ধতিগুলি কী উপস্থাপন করে? একক দায়িত্ব কী? তাদের অন্য শ্রেণি হওয়া উচিত?


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

@ জানহুদেক স্পষ্ট করেছেন।
ডেভ হিলিয়ার 11

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