অবজেক্ট ওরিয়েন্টেড লেট বাইন্ডিং


11

ইন ওরিয়েন্টড বস্তুর অ্যালান Kays সংজ্ঞা এই সংজ্ঞা আংশিকভাবে আমি বুঝতে পারছি না থাকে:

আমার কাছে ওওপি মানে কেবল বার্তা, স্থানীয় ধরে রাখা এবং সুরক্ষা এবং রাষ্ট্র-প্রক্রিয়া লুকানো এবং সমস্ত কিছুর চূড়ান্ত লেটবাইন্ডিং।

তবে "লেটবাইন্ডিং" এর অর্থ কী? আমি কীভাবে সি # এর মতো ভাষায় এটি প্রয়োগ করতে পারি? এবং কেন এটি এত গুরুত্বপূর্ণ?



2
সি # তে ওওপি সম্ভবত ওওপি অ্যালান কেয়ের মনে যে ধরণের ছিল তা নয়।
ডক ব্রাউন

আমি আপনার সাথে একমত, একেবারে ... উদাহরণগুলি যে কোনও ভাষায় স্বাগত
লুকা জুলিয়ান

উত্তর:


14

"বাঁধাই করা" একটি পদ্ধতির নামটি একটি চলতি কোডের একাংশে সমাধান করার কাজকে বোঝায়। সাধারণত, ফাংশন কলটি সংকলন সময়ে বা লিংক সময়ে সমাধান করা যেতে পারে। স্ট্যাটিক বাইন্ডিং ব্যবহার করে ভাষার উদাহরণ সি:

int foo(int x);

int main(int, char**) {
  printf("%d\n", foo(40));
  return 0;
}

int foo(int x) { return x + 2; }

এখানে, foo(40)সংকলক দ্বারা কলটি সমাধান করা যেতে পারে। এই প্রথম দিকে ইনলাইনিংয়ের মতো নির্দিষ্ট অপ্টিমাইজেশনের অনুমতি দেয়। সর্বাধিক গুরুত্বপূর্ণ সুবিধা হ'ল:

  • আমরা টাইপ চেকিং করতে পারি
  • আমরা অপ্টিমাইজেশন করতে পারি

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

def foo():
    """"call the bar() function. We have no idea what bar is."""
    return bar()

def bar():
    return 42

print(foo()) # bar() is 42, so this prints "42"

# use reflection to overwrite the "bar" variable
locals()["bar"] = lambda: "Hello World"

print(foo()) # bar() was redefined to "Hello World", so it prints that

bar = 42
print(foo()) # throws TypeError: 'int' object is not callable

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

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

#define METHOD_CALL(object_ptr, name, ...) \
  (object_ptr)->vtable->name((object_ptr), __VA_ARGS__)

typedef struct {
    void (*sayHello)(const MyObject* this, const char* yourname);
} MyObject_VTable;

typedef struct {
    const MyObject_VTable* vtable;
    const char* name;
} MyObject;

static void MyObject_sayHello_normal(const MyObject* this, const char* yourname) {
  printf("Hello %s, I'm %s!\n", yourname, this->name);
}

static void MyObject_sayHello_alien(const MyObject* this, const char* yourname) {
  printf("Greetings, %s, we are the %s!\n", yourname, this->name);
}

static MyObject_VTable MyObject_VTable_normal = {
  .sayHello = MyObject_sayHello_normal,
};
static MyObject_VTable MyObject_VTable_alien = {
  .sayHello = MyObject_sayHello_alien,
};

static void sayHelloToMeredith(const MyObject* greeter) {
   // we have no idea what the VTable contents of my object are.
   // However, we do know it has a sayHello method.
   // This is dynamic dispatch right here!
   METHOD_CALL(greeter, sayHello, "Meredith");
}

int main() {
  // two objects with different vtables
  MyObject frank = { .vtable = &MyObject_VTable_normal, .name = "Frank" };
  MyObject zorg  = { .vtable = &MyObject_VTable_alien, .name = "Zorg" };

  sayHelloToMeredith(&frank); // prints "Hello Meredith, I'm Frank!"
  sayHelloToMeredith(&zorg); // prints "Greetings, Meredith, we are the Zorg!"
}

এই ধরণের পদ্ধতি দেখার জন্য "গতিশীল প্রেরণ" এবং কোথাও কোথাও প্রাথমিক বাইন্ডিং এবং দেরী বাইন্ডিংয়ের নামে পরিচিত। আমি ডায়নামিক মেথড প্রেরণকে ওওপি প্রোগ্রামিংয়ের কেন্দ্রীয় সংজ্ঞায়িত সম্পত্তি হিসাবে বিবেচনা করি, অন্য কোনও কিছু (যেমন এনক্যাপসুলেশন, সাব টাইপিং,…) গৌণ বলে বিবেচনা করে। এটি আমাদের কোডগুলিতে পলিমারফিজমটি প্রবর্তন করতে সক্ষম করে, এমনকি কোডের কোনও অংশে এটি পুনরায় সংবিধান না করে নতুন আচরণ যুক্ত করতে সক্ষম করে! সি উদাহরণে, যে কোনও নতুন vtable যুক্ত করতে এবং সেই vtable এর সাথে একটি বস্তু পাস করতে পারে sayHelloToMeredith()

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

উদাহরণস্বরূপ, আমি প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জ.সেট সার্ভারটি জিজ্ঞাসা করতে পারি GET /questions/301919/। স্বরলিপি তুলনা করুন programmers.get("/questions/301919/")। সার্ভারটি এই অনুরোধটি প্রত্যাখ্যান করতে পারে বা আমাকে একটি ত্রুটি ফেরত পাঠাতে পারে, বা এটি আমাকে আপনার প্রশ্নের উত্তর দিতে পারে।

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

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

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


4

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

কেন? কারণ এটি সিস্টেমের অংশগুলি স্বাধীনভাবে পরিবর্তিত করার ক্ষমতাকে উত্সাহ দেয় এবং এটি জৈবিকভাবে বৃদ্ধি এবং পরিবর্তনের প্রতিশ্রুতি দেয়।

উদাহরণস্বরূপ, সি # তে আপনি এমন কোনও কিছুর জন্য কোনও পদ্ধতিতে লিখতে obj1পারেন obj2.doSomething()। আপনি এর obj1সাথে যোগাযোগ করার মত দেখতে পারেন obj2। এটি সি # তে হওয়ার জন্য, obj1সম্পর্কে মোটামুটি কিছু জানা দরকার obj2। এটির ক্লাসটি জানা দরকার ছিল। এটি পরীক্ষা করে দেখতে পেত যে ক্লাসটির একটি পদ্ধতি বলা হয়েছে doSomethingএবং সেই পদ্ধতির একটি সংস্করণ রয়েছে যা শূন্য পরামিতি নেয়।

এখন এমন একটি সিস্টেম কল্পনা করুন যেখানে আপনি কোনও নেটওয়ার্ক বা অনুরূপ কোনও বার্তা পাঠাচ্ছেন। আপনি কিছু লিখতে পারে Runtime.sendMsg(ipAddress, "doSomething")। এই ক্ষেত্রে আপনি যে মেশিনটির সাথে যোগাযোগ করছেন সে সম্পর্কে আপনাকে অনেক কিছু জানার দরকার নেই; সম্ভবত এটি আইপি এর মাধ্যমে যোগাযোগ করা যেতে পারে এবং "ডসোমিংথিং" স্ট্রিংটি পেয়ে গেলে এটি কিছু করবে। তবে অন্যথায় আপনি খুব কম জানেন।

এখন কল্পনা করুন যে কীভাবে অবজেক্ট যোগাযোগ করে। আপনি একটি ঠিকানা জানেন এবং আপনি যে ঠিকানায় কোনও ধরণের "পোস্টবক্স" ফাংশন দিয়ে স্বেচ্ছাচারিত বার্তা প্রেরণ করতে পারেন। এই ক্ষেত্রে, এটি obj1সম্পর্কে খুব বেশি জানা দরকার নেই obj2। এমনকি এটি বুঝতে পারার প্রয়োজন নেই doSomething

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

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

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

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