পিএইচপি-তে অবৈধ: কোনও ওওপি নকশার কারণ আছে?


16

নীচের ইন্টারফেসের উত্তরাধিকার পিএইচপি-তে অবৈধ, তবে আমি মনে করি এটি বাস্তব জীবনে মোটামুটি কার্যকর হবে। নীচের ডিজাইনের সাথে সত্যিকারের অ্যান্টিপ্যাটার্ন বা নথিভুক্ত সমস্যা আছে, যা পিএইচপি আমাকে রক্ষা করছে?

<?php

/**
 * Marker interface
 */
interface IConfig {}

/**
 * An api sdk tool
 */
interface IApi
{
    public __construct(IConfig $cfg);
}

/**
 * Api configuration specific to http
 */
interface IHttpConfig extends IConfig
{
    public getSomeNiceHttpSpecificFeature();
}

/**
 * Illegal, but would be really nice to have.
 * Is this not allowed by design?
 */
interface IHttpApi extends IApi
{
    /**
     * This constructor must have -exactly- the same
     * signature as IApi, even though its first argument
     * is a subtype of the parent interface's required
     * constructor parameter.
     */
    public __construct(IHttpConfig $cfg);

}

উত্তর:


22

আসুন একটি সেকেন্ডের জন্য উপেক্ষা করুন যে প্রশ্নে পদ্ধতিটি হল __constructএবং এটি কল করুন frobnicate। এখন ধরুন আপনার কাছে একটি অবজেক্ট apiবাস্তবায়নকারী IHttpApiএবং একটি অবজেক্ট configবাস্তবায়নকারী রয়েছে IHttpConfig। স্পষ্টতই, এই কোডটি ইন্টারফেসের সাথে ফিট করে:

$api->frobnicate($config)

তবে ধরা যাক আমরা উদাহরণস্বরূপ উপুড় apiহয়ে যাই IApi, উদাহরণস্বরূপ এটিকে পাস করা function frobnicateTwice(IApi $api)। এখন যে ফাংশনে, frobnicateবলা হয়, এবং যেহেতু এটি শুধুমাত্র সঙ্গে পুলিশ IApi, এটা যেমন যেমন একটি কল সঞ্চালন করা সম্ভব $api->frobnicate(new SpecificConfig(...))যেখানে SpecificConfigকার্যকরী IConfigকিন্তু IHttpConfig। বিন্দুতে কেউ প্রকারের সাথে অস্বাস্থ্যকর কিছু করেনি, তবে এমনটি IHttpApi::frobnicateপেয়েছে SpecificConfigযেখানে এটি প্রত্যাশিত IHttpConfig

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

সাধারণত, আপনি বহুকর্ম, বৈচিত্রকে ঘিরে একটি ক্লাসিক ফাঁদে গেছেন । কোনও ধরণের সমস্ত ঘটনা Tউপ- টাইপ দ্বারা প্রতিস্থাপন করা যায় না U। বিপরীতভাবে, কোনও ধরণের সমস্ত ঘটনাকে Tএকটি সুপারটাইপ দ্বারা প্রতিস্থাপন করা যায় নাS । সাবধানতার সাথে বিবেচনা (বা আরও ভাল, ধরণের তত্ত্বের কঠোর প্রয়োগ) প্রয়োজনীয়।

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


19

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

এটি ছাড়াও অন্যান্য পদ্ধতিতে এটি আরও স্পষ্ট __construct। বিবেচনা:

class Vehicle {}
class Car extends Vehicle {}
class Motorcycle extends Vehicle {}

class Driver {
    public drive(Vehicle $v) { ... }
}
class CarDriver extends Driver {
    public drive(Car $c) { ... }
}

একটি CarDriverএকটি হল Driverতাই একটি, CarDriverউদাহরণস্বরূপ কাজ করতে সক্ষম হওয়া আবশ্যক কিছু যে একটি Driverপারবেন না। ড্রাইভিং সহ Motorcycles, কারণ এটি কেবল একটি Vehicle। তবে এর পক্ষে যুক্তির ধরণটি driveবলে যে একটি CarDriverকেবল Carএস চালাতে পারে - একটি বৈপরীত্য: এর যথাযথ উপক্লাস হতে CarDriver পারে নাDriver

বিপরীত আরও জ্ঞান করে:

class CarDriver {
    public drive(Car $c) { ... }
}
class MultiTalentedDriver extends CarDriver {
    public drive(Vehicle $v) { ... }
}

CarDriverকেবল Carএস চালাতে পারে । একজন MultiTalentedDriverএছাড়াও ড্রাইভ করতে পারেন Carএস, কারণ একটি Carএকটি ঠিক হয় Vehicle। অতএব, MultiTalentedDriverএকটি সঠিক সাবক্লাস হয় CarDriver

আপনার উদাহরণে, যে কোনওটি IApiএকটি দিয়ে নির্মিত যেতে পারে IConfig। যদি IHttpApiএর একটি উপপ্রকার হয় IApi, আমাদের অবশ্যই IHttpApiকোনও IConfigউদাহরণ ব্যবহার করে একটি নির্মাণ করতে সক্ষম হতে হবে - তবে এটি কেবল গ্রহণ করে IHttpConfig। এটি একটি দ্বন্দ্ব।


সমস্ত ড্রাইভার উভয় গাড়ি এবং মোটরসাইকেল চালাতে পারে না ...
sakisk

3
@ ফিফ: এই বিশেষ বিমূর্তিতে তারা কেবল পারেন না, তাদের অবশ্যই আবশ্যক। কারণ, হিসাবে আপনি দেখতে পারেন, একটি Driverকোনো ড্রাইভ করতে পারেন Vehicleএবং যেহেতু উভয় Carএবং Motorcycleপ্রসারিত Vehicle, সমস্ত Driverগুলি উভয় হ্যান্ডেল করতে সক্ষম হতে হবে।
অ্যালেক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.