কীভাবে নকশার ধরণগুলি এবং ওওপি অনুশীলনগুলির উপর চিন্তাভাবনা গতিশীল এবং দুর্বল টাইপযুক্ত ভাষাগুলিতে পরিবর্তিত হয়?


11

ইতিমধ্যে এই রেখাগুলিতে (" নন-ওওপি নকশার প্যাটার্নস? ") বরাবর বেশ কার্যকর প্রশ্ন রয়েছে তবে আমি গতিশীল এবং দুর্বল-টাইপিত ভাষা দিয়ে শুরু করা কারওর জন্য একটি ক্রান্তিকালীন দৃষ্টিভঙ্গি সম্পর্কে আরও আগ্রহী।

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

কি একই থাকে? কি পরিবর্তন? সলাইডের মতো গাইডিং নীতিগুলি, বা গতিময় ভাষার নবাগতদের জানা থাকা ক্যানোনিকাল প্যাটার্নগুলি (সম্ভবত সম্পূর্ণ নতুন) থাকতে পারে?

উত্তর:


7

কি একই থাকে? কি পরিবর্তন?

নিদর্শন একই। ভাষার কৌশল বদলে যায়।

SOLID এর মতো গাইডিং নীতিগুলি রয়েছে কি?

হ্যাঁ. নিঃসন্দেহে এরা পথনির্দেশক নীতিসমূহ। কিছুই পরিবর্তন.

বা ক্যানোনিকাল নিদর্শনগুলি (সম্ভবত সম্পূর্ণ নতুন) একটি গতিময় ভাষার নবাগত জানা উচিত?

কিছু জিনিস অনন্য। বেশিরভাগ ক্ষেত্রে প্রভাবটি বাস্তবায়নের কৌশলগুলি পরিবর্তিত হয়।

একটি নিদর্শন - ভাল - একটি নিদর্শন । আইন নয়। সাবরুটিন নয়। ম্যাক্রো নয়। এটি কেবল একটি ভাল ধারণা যা পুনরাবৃত্তি হয় কারণ এটি একটি ভাল ধারণা।

ভাল ধারণা স্টাইলের বাইরে যায় না বা নাটকীয়ভাবে পরিবর্তন হয় না।

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

এছাড়াও। বেশিরভাগ ডিজাইনের নিদর্শনগুলি পলিমারফিজম শোষণের বিভিন্ন উপায়ে ভিত্তিক।

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

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

কিছু নিদর্শনগুলি সংকলক এবং লিঙ্কার চালনার চেষ্টা। একক , উদাহরণস্বরূপ, বিভ্রান্তিকর globals তৈরি করতে কিন্তু অন্তত তাদের encapsulate বিদ্যমান। পাইথন সিঙ্গলটন ক্লাসগুলি সুখকর সম্ভাবনা নয়। তবে পাইথন মডিউলগুলি ইতিমধ্যে সিঙ্গলেটন, তাই আমাদের মধ্যে অনেকে কেবল একটি মডিউল ব্যবহার করে এবং একটি একক ক্লাসের সাথে ঝামেলা করার চেষ্টা এড়ায়


আমি বলব না যে সলিডের সাথে "কিছুই পরিবর্তন হয় না"। ভাষা এবং তার অবজেক্টের মডেলের উপর নির্ভর করে ওপেন-ক্লোজড প্রিন্সিপাল এবং লিসকভ সাবস্টিটিউশন নীতি উভয় অর্থহীন হতে পারে। (জাভাস্ক্রিপ্ট এবং গো দু'জনেরই মনে আসে))
ম্যাসন হুইলার

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

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

@ এস.লোট: কারণ ওপেন / ক্লোজড উত্তরাধিকার সম্পর্কে, যা সেই ভাষাগুলির নেই। (এছাড়াও, কোনও সামগ্রীর "পরিবর্তনের জন্য বন্ধ" হওয়ার ধারণাটি অনেকগুলি রুবি কোডার দিয়ে ভাল বসবে না ...)
ম্যাসন হুইলার

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

8

পিটার নরভিগ ১৯৯৯ সালে এই একই প্রশ্নটি নিয়েছিলেন, তিনি লক্ষ্য করেছেন এমন একটি বিস্তৃত জিনিসের জন্য http://norvig.com/design-patterns/ppframe.htm পড়ুন এবং http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFishesures এর জন্য পয়েন্ট চারপাশে আরও আলোচনা।

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


8

একটি গতিশীল অবজেক্ট ওরিয়েন্টেড ল্যাঙ্গুয়েজে প্রোগ্রামিংয়ে একই ধরণের অনেকগুলি নীতি এবং নীতি ব্যবহার করা হয় তবে পরিবেশের কারণে কিছু নির্দিষ্ট টুইট এবং পার্থক্য রয়েছে:

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

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

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

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


3

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

একটি ক্রিয়েশনাল প্যাটার্ন স্থাপন করার পরিবর্তে প্রায়শই যথেষ্ট যা যথেষ্ট পরিমাণে কল করে যা বস্তু তৈরি করে। এটি কোনও ফাংশন, কোনও __call__পদ্ধতি বা এমনকি কোনও শ্রেণি সহ একটি বস্তু হতে পারে , যেহেতু new()পাইথনে কোনও নেই , কেবল শ্রেণির নিজেই একটি আহবান:

def make_da_thing(maker, other, stuff):
    da_thing = maker(other + 1, stuff + 2)
    # ... do sth
    return da_thing

def maker_func(x, y):
     return x * y

class MakerClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
...
a = make_da_thing(maker_func, 5, 8)
b = make_da_thing(MakerClass, 6, 7)

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

class On(object):
    is_on = True
    def switch(self):
        self.__class__ = Off

class Off(object):
    is_on = False
    def switch(self):
        self.__class__ = On
...

my_switch = On()
assert my_switch.is_on
my_switch.switch()
assert not my_switch.is_on

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

class Visitable(object):
    def accept(self, visitor):
        visit = getattr(visitor, 'visit' + self.__class__.__name__)
        return visit(self)
...

class On(Visitable):
    ''' exactly like above '''

class Off(Visitable):
    ''' exactly like above '''

class SwitchStatePrinter(object): # Visitor
    def visitOn(self, switch):
         print 'the switch is on'
    def visitOff(self, switch):
         print 'the switch is off'

class SwitchAllOff(object): # Visitor
    def visitOn(self, switch):
         switch.switch()
    def visitOff(self, switch):
         pass
...
print_state = SwitchStatePrinter()
turn_em_off = SwitchAllOff()
for each in my_switches:
    each.accept(print_state)
    each.accept(turn_em_off)

স্ট্যাটিক ল্যাঙ্গুয়েজে কোনও প্যাটার্ন প্রয়োগের জন্য কল করা অনেকগুলি পরিস্থিতি পাইথনে তেমন করে না। উচ্চতর অর্ডার ফাংশন (ডেকোরেটর, ফাংশন কারখানা) বা মেটা ক্লাসের মতো অনেক জিনিসই অন্যান্য থেকনিউকের সাথে সমাধান করা যায়।


আমি এখন বুঝতে পেরেছি যে আপনার উত্তর শিরোনামে আমি সবে জিজ্ঞাসা করা প্রশ্নটি কভার করে: পাইথনের কোনও কারখানা বাস্তবায়নের জন্য ওভাররাইট __class__করা কি ভাল ধারণা?
আরডিএস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.