একটি শ্রেণীর জন্য প্যাটার্ন যা কেবল একটি কাজ করে


24

ধরা যাক আমার কাছে এমন একটি পদ্ধতি রয়েছে যা স্টাফ করে :

void doStuff(initalParams) {
    ...
}

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

class StuffDoer {
    private someInternalState;

    public Start(initalParams) {
        ...
    }

    // some private helper procedures here
    ...
}

এবং তারপরে আমি এটিকে এভাবে ডাকি:

new StuffDoer().Start(initialParams);

বা এই মত:

new StuffDoer(initialParams).Start();

এবং এটিই ভুল বলে মনে হচ্ছে। .NET বা জাভা API ব্যবহার করার সময়, আমি সবসময় কখনও কল করি না new SomeApiClass().Start(...);, যা আমাকে সন্দেহ করে যে আমি এটি ভুল করছি। অবশ্যই, আমি স্টাফডোয়ারের কনস্ট্রাক্টরকে ব্যক্তিগত করতে পারি এবং একটি স্থিতিশীল সহায়ক পদ্ধতি যুক্ত করতে পারি:

public static DoStuff(initalParams) {
    new StuffDoer().Start(initialParams);
}

তবে তারপরে আমার একটি শ্রেণি থাকবে যার বাহ্যিক ইন্টারফেসটি কেবলমাত্র একটি স্থিতিশীল পদ্ধতি নিয়ে গঠিত, যা অদ্ভুত মনে হয়।

সুতরাং আমার প্রশ্ন: এই ধরণের শ্রেণির জন্য একটি সু-প্রতিষ্ঠিত প্যাটার্ন রয়েছে কি?

  • শুধুমাত্র একটি প্রবেশ পয়েন্ট এবং
  • কোন "বাহ্যিকরূপে স্বীকৃতিযোগ্য" রাষ্ট্র নেই, অর্থাত্‍ one প্রবেশ দফার প্রয়োগের সময় উদাহরণস্বরূপ রাষ্ট্রের প্রয়োজন ?

আমি এমন জিনিসগুলি করতে গিয়ে পরিচিত bool arrayContainsSomestring = new List<string>(stringArray).Contains("somestring");ছিলাম যখন আমার যত্ন নেওয়া সমস্ত ছিল সেই নির্দিষ্ট তথ্য এবং লিংকউ এক্সটেনশন পদ্ধতিগুলি উপলভ্য নয়। সূক্ষ্মভাবে কাজ করে এবং if()হুপসের মাধ্যমে ঝাঁপিয়ে পড়ার দরকার ছাড়াই একটি অবস্থার সাথে ফিট করে । অবশ্যই আপনি কোনও আবর্জনা-সংগৃহীত ভাষা চান যদি আপনি এর মতো কোড লিখছেন।
একটি সিভিএন


আমি কৌতূহলী, এই 'এক পদ্ধতি' এর কার্যকারিতা কী? সুনির্দিষ্ট দৃশ্যে সেরা পদ্ধতির কী তা নির্ধারণে এটি একটি দুর্দান্ত সাহায্য করবে তবে তবুও আকর্ষণীয় প্রশ্ন!
স্টিভেন জিউরিস

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

1
উদাহরণটি তৈরি করার সময় আপনি যদি সবসময় পদ্ধতিটি কল করেন তবে কেন এটি নির্মাণকারীর অভ্যন্তরে একটি প্রাথমিক যুক্তি তৈরি করবেন না?
NoChance

উত্তর:


29

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

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


1
এটি আমি যা করছি ঠিক এর মতো শোনাচ্ছে। ধন্যবাদ, কমপক্ষে এটির জন্য এখন আমার একটি নাম আছে। :-)
হেইনজি

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


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

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

13

আমি বলব যে প্রশ্নে ক্লাস (একক প্রবেশ পয়েন্ট ব্যবহার করে) ভালভাবে ডিজাইন করা হয়েছে। এটি ব্যবহার করা এবং প্রসারিত করা সহজ। বেশ সলিড।

একই জিনিস no "externally recognizable" state। এটি ভাল encapsulation।

কোডের মতো কোনও সমস্যা আমি দেখতে পাচ্ছি না:

var doer = new StuffDoer(initialParams);
var result = doer.Calculate(extraParams);

1
এবং অবশ্যই, যদি আপনার doerআবার এটি ব্যবহার করার প্রয়োজন না হয় তবে তা হ্রাস পায় var result = new StuffDoer(initialParams).Calculate(extraParams);
একটি সিভিএন

গণনাটির নামকরণ করা হবে ডস্টফ!
shabunc

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

2
এই উত্তর অত্যধিক সরল। আপনি StringComparerযেমন ক্লাস ব্যবহার করেন তেমন new StringComparer().Compare( "bleh", "blah" )ডিজাইনও করেন? রাষ্ট্র তৈরির বিষয়ে কী নেই যখন সম্পূর্ণরূপে প্রয়োজন হয় না? ঠিক আছে, আচরণটি ভালভাবে আবদ্ধ (ভাল, কমপক্ষে শ্রেণীর ব্যবহারকারীর কাছে, আমার উত্তরটিতে এটি আরও বেশি ) তবে এটি ডিফল্টরূপে 'ভাল ডিজাইন' করে না। আপনার 'কর্তা-ফলাফল' উদাহরণ হিসাবে। আপনি যদি কখনও এর doerথেকে পৃথক ব্যবহার করেন তবে এটি কেবল অর্থযুক্ত হবে result
স্টিভেন জিউরিস

1
এটি বিদ্যমান থাকার এক কারণ নয়, এটি one reason to change। পার্থক্যটি সূক্ষ্ম বলে মনে হতে পারে। এর অর্থ কী তা বুঝতে হবে। এটি কখনই একটি পদ্ধতির ক্লাস তৈরি করতে পারে না
jgauffin

8

একটি SOLID নীতি দৃষ্টিকোণ থেকে jgauffin এর উত্তর উপলব্ধি করে তোলে। তবে আপনার সাধারণ নকশার নীতিগুলি যেমন তথ্য গোপন করা ভুলে যাওয়া উচিত নয় ।

আমি প্রদত্ত পদ্ধতির সাথে বেশ কয়েকটি সমস্যা দেখতে পাচ্ছি:

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

কিছু সম্পর্কিত রেফারেন্স

সম্ভবত আর্গুমেন্টের একটি মূল বিন্দু কতদূর প্রসারিত করার জন্য মিথ্যা একক দায়িত্ব নীতি"আপনি যদি এটিকে চূড়ান্ত দিকে নিয়ে যান এবং ক্লাসগুলি তৈরির কারণগুলির একটি কারণ রয়েছে যা আপনি তৈরি করতে পারেন তবে প্রতি ক্লাসে কেবলমাত্র একটি পদ্ধতি থাকতে পারে। এটি প্রক্রিয়াগুলির এমনকি সবচেয়ে সাধারণ পদ্ধতির জন্য ক্লাসগুলির একটি বৃহত বিস্তৃতি সৃষ্টি করবে, যার ফলে সিস্টেমটি হবে বুঝতে সহজ এবং পরিবর্তন করা কঠিন। "

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

তাহলে সঠিক পন্থাটি কী?

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

new TupleList<Key, int>
{
    { Key.NumPad1, 1 },
            ...
    { Key.NumPad3, 16 },
    { Key.NumPad4, 17 },
}
    .ForEach( t =>
    {
        var trigger = new IC.Trigger.EventTrigger(
                        new KeyInputCondition( t.Item1, KeyInputCondition.KeyState.Down ) );
        trigger.ConditionsMet += () => AddMarker( t.Item2 );
        _inputController.AddTrigger( trigger );
    } );

যেহেতু খুব 'স্থানীয়' কোডটি ForEachঅন্য কোথাও পুনরায় ব্যবহার করা হয়নি, তাই আমি কেবল এটি যথাযথ স্থানে রাখতে পারি it কোডটি এমনভাবে আউটলাইন করে যাতে একে অপরের উপর নির্ভর করে এমন কোড যা দৃ strongly়ভাবে একত্রে গোষ্ঠীযুক্ত হয় তা আমার মতে এটি আরও পাঠযোগ্য।

সম্ভাব্য বিকল্প

  • সি # তে আপনি এর পরিবর্তে এক্সটেনশন পদ্ধতিগুলি ব্যবহার করতে পারেন। সুতরাং আপনি সরাসরি এই 'এক জিনিস' পদ্ধতিতে তর্কটি চালিয়ে যান।
  • দেখুন এই ফাংশনটি আসলে অন্য শ্রেণীর নয়।
  • স্ট্যাটিক ক্লাসে এটি একটি স্ট্যাটিক ফাংশন করুন । এটি সম্ভবত সবচেয়ে উপযুক্ত পন্থা, যেমনটি আপনি উল্লেখ করেছেন এমন সাধারণ API গুলিও প্রতিফলিত হয়।

পলটারজিস্ট, অন্য উত্তরে বর্ণিত হিসাবে আমি এই অ্যান্টি-প্যাটার্নটির একটি সম্ভাব্য নাম পেয়েছি ।
স্টিভেন জিউরিস

4

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


কি দারুন! আমার চেয়ে অনেক বেশি সংক্ষিপ্তভাবে আপনি এর অঙ্গভঙ্গিতে পৌঁছতে সক্ষম হয়েছেন। :) ধন্যবাদ। (অবশ্যই আমি কিছুটা এগিয়ে যেতে পারি যেখানে আমরা দ্বিমত পোষণ করতে পারি, তবে আমি সাধারণ ভিত্তিতে একমত)
স্টিভেন জিউরিস

2
new StuffDoer().Start(initialParams);

অজ্ঞাত বিকাশকারীদের সাথে একটি সমস্যা রয়েছে যারা ভাগ করে নেওয়া উদাহরণ ব্যবহার করতে এবং এটি ব্যবহার করতে পারে

  1. একাধিক বার (ঠিক আছে যদি পূর্বের (সম্ভবত আংশিক) কার্যকর করা পরে মৃত্যুদন্ড কার্যকর না করে)
  2. একাধিক থ্রেড থেকে (ঠিক আছে না, আপনি স্পষ্টভাবে বলেছেন এর অভ্যন্তরীণ অবস্থা রয়েছে)।

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

একটি স্থিতিশীল পদ্ধতিতে এটিকে আড়াল করা এটিকে সাহায্য করে কারণ এরপরে উদাহরণটি পুনরায় ব্যবহার করা কখনই ঘটে না।

যদি কিছু দামী আরম্ভের আছে, এটা পারা (এটা সবসময় হয়) এটি একবার আরম্ভের এবং এটি অন্য বর্গ যে শুধুমাত্র রাষ্ট্র থাকে এবং এটা cloneable করতে হবে তৈরি করে একাধিক বার ব্যবহার প্রস্তুতির উপকারী হতে। সূচনাটি এমন স্টেট তৈরি করবে যা সংরক্ষণ করা হবে doerstart()এটি ক্লোন করে অভ্যন্তরীণ পদ্ধতিতে পাঠিয়ে দেবে।

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


ভাল দিক. আশা করি আপনি পরিষ্কার করতে আপত্তি করবেন না।
স্টিভেন জিউরিস

2

আমার আরও বিস্তৃত, ব্যক্তিগতকৃত অন্যান্য উত্তর ছাড়াও , আমি মনে করি যে নিম্নলিখিত পর্যবেক্ষণটি একটি পৃথক উত্তরের দাবিদার।

এমন ইঙ্গিত রয়েছে যে আপনি পলটারজিস্ট বিরোধী-প্যাটার্ন অনুসরণ করছেন

Poltergeists খুব সীমিত ভূমিকা এবং কার্যকর জীবন চক্র সহ ক্লাস হয়। তারা প্রায়শই অন্যান্য বস্তুর জন্য প্রক্রিয়া শুরু করে। রিফ্যাক্টরড সমাধানটিতে দীর্ঘস্থায়ী বস্তুর প্রতি দায়িত্ব পুনর্বিবেচনা অন্তর্ভুক্ত যা Poltergeists কে নির্মূল করে।

লক্ষণ ও ফলাফল se

  • অপ্রয়োজনীয় নেভিগেশন পাথ।
  • ক্ষণস্থায়ী সমিতি
  • রাষ্ট্রহীন ক্লাস।
  • অস্থায়ী, স্বল্প-মেয়াদী অবজেক্ট এবং ক্লাস।
  • একক-অপারেশন ক্লাস যা অস্থায়ী সংস্থার মাধ্যমে কেবল অন্য বর্গ "বীজ" বা "প্রার্থনা" করে থাকে।
  • স্টার্ট_প্রসেস_সালফার মতো "কন্ট্রোল-মত" অপারেশন নামের ক্লাস।

রিফ্যাক্টর সলিউশন

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


0

EAA ক্যাটালগের মার্টিন ফোলারের পিতে বেশ কয়েকটি নিদর্শন পাওয়া যায় ;

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