ইন্টারফেস ধ্রুবকগুলির প্রস এবং কনস [বন্ধ]


105

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

interface FooBar
{
    const FOO = 1;
    const BAR = 2;
}
echo FooBar::FOO; // 1

যে কোনও বাস্তবায়নকারী শ্রেণীর কাছে স্বয়ংক্রিয়ভাবে এই ধ্রুবকগুলি উপলব্ধ থাকবে eg

class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1

আমার নিজের গ্রহণ এটি হ'ল গ্লোবাল যে কোনও কিছুই .ভিল । তবে আমি অবাক হই যে এটি ইন্টারফেস কনস্ট্যান্টগুলির ক্ষেত্রে প্রযোজ্য কিনা। প্রদত্ত যে একটি ইন্টারফেস বিরুদ্ধে কোডিং ভাল অভ্যাস বলে মনে করা হয় সাধারণভাবে ইন্টারফেস ধ্রুবক শুধুমাত্র ধ্রুবক একটি বর্গ প্রসঙ্গ বাহিরে ব্যবহার করতে গ্রহণযোগ্য ব্যবহার করছেন?

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

দ্রষ্টব্য: জাভা সম্পর্কিত একটি অনুরূপ প্রশ্ন রয়েছে যেগুলি খারাপ অভ্যাসের কারণগুলির বেশ কয়েকটি ভাল কারণ তালিকাভুক্ত করেছে, তবে যেহেতু জাভা পিএইচপি নয়, তাই আমি পিএইচপি ট্যাগের মধ্যে আবার এটি জিজ্ঞাসা করা ন্যায়সঙ্গত অনুভব করেছি।


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

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

উত্তর:


135

ঠিক আছে, আমি মনে করি এটি যথেষ্ট ভাল এবং যথেষ্ট মধ্যে পার্থক্য ডান ।

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

খারাপ:

interface User {
    const TYPE_ADMINISTRATOR = 1;
    const TYPE_USER          = 2;
    const TYPE_GUEST         = 3;
}

যথেষ্ট:

interface HTTPRequest_1_1 {
    const TYPE_CONNECT = 'connect';
    const TYPE_DELETE  = 'delete';
    const TYPE_GET     = 'get';
    const TYPE_HEAD    = 'head';
    const TYPE_OPTIONS = 'options';
    const TYPE_POST    = 'post';
    const TYPE_PUT     = 'put';

    public function getType();
}

এখন, যে কারণগুলি আমি এই উদাহরণগুলি বেছে নিয়েছি তা সহজ। Userইন্টারফেস ব্যবহারকারী ধরনের একটি enum সংজ্ঞা করা হয়। এটি সময়ের সাথে সাথে প্রসারিত হওয়ার খুব সম্ভবত এবং এটি অন্য প্যাটার্নের দ্বারা আরও উপযুক্ত। তবে এটি HTTPRequest_1_1একটি শালীন ব্যবহারের ক্ষেত্রে, যেহেতু এনামটি আরএফসি 2616 দ্বারা সংজ্ঞায়িত হয়েছে এবং শ্রেণীর আজীবন পরিবর্তিত হবে না।

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

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

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

আবার, এটি সম্পর্কে আমার দৃষ্টিভঙ্গি ...


4
এক্ষেত্রে ব্যবহারকারীর জন্য আলাদা প্যাটার্ন হিসাবে আপনি কী পরামর্শ করবেন?
জ্যাকব

@ জ্যাকব: আমি এটিকে বিমূর্ত করবো। আপনার প্রয়োজনের উপর নির্ভর করে, আমি সম্ভবত একটি অ্যাক্সেস ক্লাস তৈরি করব যা একটি ডেটাবেস টেবিল থেকে তার ডেটা পেতে পারে। এইভাবে একটি নতুন স্তর যুক্ত করা যেমন একটি নতুন সারি সন্নিবেশ করা ঠিক তত সহজ। আরেকটি বিকল্প হ'ল একটি ENUM বর্গ সেট তৈরি করা (যেখানে প্রতিটি অনুমতি ভূমিকার জন্য আপনার একটি শ্রেণি থাকে)। তারপরে আপনি প্রয়োজনীয় অনুমতিগুলি সরবরাহ করার জন্য প্রয়োজনীয় ক্লাসগুলি প্রসারিত করতে পারেন। তবে অন্যান্য পদ্ধতি রয়েছে যা খুব কার্যকর হবে
ircmaxell

3
খুব দৃ and় এবং ভাল উত্তর! +1
ডিসেন্ট ড্যাবলার

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

2
@FrederikKrautwald: আপনি পলিমরফিজম (অধিকাংশ ক্ষেত্রে) সঙ্গে কন্ডিশন এড়াতে পারেন: চেক করুন এই উত্তর জানতে সেইসাথে এই ক্লিন কোড আলাপ ঘড়ি ...
ircmaxell

10

আমি মনে করি যে আপনার ইন্টারফেস থেকে পৃথক ধরণের ("শ্রেণি") হিসাবে ধ্রুবকগুলি, বিশেষত গণনা করা ধ্রুবকগুলি পরিচালনা করা সাধারণত ভাল better

define(TYPE_CONNECT, 'connect');
define(TYPE_DELETE , 'delete');
define(TYPE_GET    , 'get');
define(TYPE_HEAD   , 'head');
define(TYPE_OPTIONS, 'options');
define(TYPE_POST   , 'post');
define(TYPE_PUT    , 'put');

interface IFoo
{
  function /* int */ readSomething();
  function /* void */ ExecuteSomething(/* int */ param);
}

class CBar implements IFoo
{
  function /* int */ readSomething() { ...}
  function /* void */ ExecuteSomething(/* int */ param) { ... }
}

বা, আপনি যদি একটি ক্লাসটি নামের স্থান হিসাবে ব্যবহার করতে চান:

class TypeHTTP_Enums
{
  const TYPE_CONNECT = 'connect';
  const TYPE_DELETE  = 'delete';
  const TYPE_GET     = 'get';
  const TYPE_HEAD    = 'head';
  const TYPE_OPTIONS = 'options';
  const TYPE_POST    = 'post';
  const TYPE_PUT     = 'put';
}

interface IFoo
{
  function /* int */ readSomething();
  function /* void */ ExecuteSomething(/* int */ param);
}

class CBar implements IFoo
{
  function /* int */ readSomething() { ...}
  function /* void */ ExecuteSomething(/* int */ param) { ... }
}

এটি এমন নয় যে আপনি কেবল ধ্রুবক ব্যবহার করছেন, আপনি গণনা করা মান বা গণনার ধারণাটি ব্যবহার করছেন, যা সীমাবদ্ধ মানগুলির একটি সেটকে একটি নির্দিষ্ট ব্যবহার হিসাবে ("ডোমেন"?) দিয়ে একটি নির্দিষ্ট ধরণের হিসাবে বিবেচনা করা হয়

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