কোনও উপায়ে কোনও পদ্ধতিতে পাস করা যা বস্তুর পরিবর্তন করে, এটি কি সাধারণ (বিরোধী) প্যাটার্ন?


17

আমি মার্টিন ফোলারের রিফ্যাক্টরিং বইতে প্রচলিত কোডের গন্ধ সম্পর্কে পড়ছি । সেই প্রসঙ্গে, আমি একটি কোড বেসে যে প্যাটার্নটি দেখছি তা নিয়ে আমি ভাবছিলাম, এবং অন্যটি অবাস্তবভাবে এটিকে একটি অ্যান্টি-প্যাটার্ন হিসাবে বিবেচনা করতে পারে।

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

var something = new Thing();
// ...
Foo(something);
int result = Bar(something, 42);
Baz(something);

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

আমি নতুন রাষ্ট্রের সাথে অন্য কোনও (ক্লোনড) অবজেক্ট, বা কল-সাইটটিতে অবজেক্টটি পরিবর্তন করার জন্য প্রয়োজনীয় যে কোনও কিছু ফেরত দেওয়ার জন্য এই জাতীয় কোডটি উন্নত করার প্রস্তাব দিতে চাই।

var something1 =  new Thing();
// ...

// Let's return a new instance of Thing
var something2 = Foo(something1);

// Let's use out param to 'return' other info about the operation
int result;
var something3 = Bar(something2, out result);

// If necessary, let's capture and make explicit complex changes
var changes = Baz(something3)
something3.Apply(changes);

আমার কাছে মনে হয় অনুমানের উপর প্রথম প্যাটার্নটি বেছে নেওয়া হয়েছে

  • এটি কম কাজ, বা কোডের কম লাইনের প্রয়োজন that
  • এটি আমাদের উভয়কে অবজেক্টটি পরিবর্তন করতে এবং কিছু অন্যান্য তথ্য ফেরত দেওয়ার অনুমতি দেয়
  • যেহেতু আমাদের কম উদাহরণ রয়েছে সেহেতু এটি আরও কার্যকর Thing

আমি একটি বিকল্প চিত্রিত করেছি, তবে এটির প্রস্তাব দেওয়ার জন্য, আমাদের মূল সমাধানটির বিরুদ্ধে যুক্তি থাকা দরকার। আসল সমাধানটি একটি বিরোধী-নিদর্শন হিসাবে কেস তৈরি করতে যুক্তি দেওয়া যেতে পারে?

এবং আমার বিকল্প সমাধানে কোনটি যদি ভুল হয়?



1
@ ডেভহিলিয়ার ধন্যবাদ, আমি এই শব্দটির সাথে পরিচিত ছিলাম, তবে সংযোগ তৈরি করিনি।
মিশিগেল ভ্যান অস্টারহাট

উত্তর:


9

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

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

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


1
উদাহরণস্বরূপ, আমার কাছে যদি একটি "ফাইল" অবজেক্ট থাকে তবে আমি কোনও স্টেটের পরিবর্তনের পদ্ধতিটিকে সেই বস্তুর মধ্যে স্থানান্তরিত করার চেষ্টা করব না - যা এসআরপি লঙ্ঘন করবে। "ফাইল" এর মতো লাইব্রেরি ক্লাসের পরিবর্তে আপনার নিজের ক্লাস থাকা সত্ত্বেও এটি বৈধ থাকে - প্রতিটি রাজ্যের রূপান্তর যুক্তিকে বস্তুর শ্রেণিতে স্থাপন করা আসলেই বোঝা যায় না।
ডক ব্রাউন

@ টেটাস্টিন আমি জানি এটি পুরানো উত্তর, তবে আমি আপনার পরামর্শটি শেষ অনুচ্ছেদে কংক্রিটের শর্তে কল্পনা করতে সমস্যা করছি। আপনি বিস্তারিত বা উদাহরণ দিতে পারেন?
অ্যারোনএলএস

@ অ্যারোনলএস - Bar(something)(এবং রাষ্ট্রের অবস্থা পরিবর্তন করে something) পরিবর্তে এর ধরণের Barসদস্য তৈরি করুন somethingsomething.Bar(42)পরিবর্তন ঘটান হবার সম্ভাবনা অধিক something, যখন আপনি OO যেমন পণ্য টুলস (ব্যক্তিগত রাষ্ট্র, ইন্টারফেস, ইত্যাদি) ব্যবহার করতে রক্ষা করতে সক্ষম হবেন something'র রাষ্ট্র
Telastyn

14

যখন পদ্ধতিগুলির যথাযথ নামকরণ করা হয় না

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

void AddMessageToLog(Logger logger, string msg)
{
    //...
}

অথবা

void StripInvalidCharsFromName(Person p)
{
// ...
}

অথবা

void AddValueToRepo(Repository repo,int val)
{
// ...
}

অথবা

void TransferMoneyBetweenAccounts(Account source, Account destination, decimal amount)
{
// ...
}

বা এর মতো কিছু - আমি এই পদ্ধতির জন্য কোনও ক্লোন করা বস্তুটি ফেরত দেওয়ার কোনও কারণ এখানে দেখছি না এবং তাদের বাস্তবায়নের দিকে নজর দেওয়ার কোনও কারণও নেই তা বুঝতে পেরে যে তারা পাশ করা বস্তুর অবস্থার পরিবর্তন করবে change

আপনি যদি পার্শ্ব প্রতিক্রিয়া না চান, আপনার অবজেক্টগুলিকে অপরিবর্তনীয় করে তুলুন, এটি মূলগুলির পরিবর্তন না করে পরিবর্তিত (ক্লোনড) বস্তুটি ফিরিয়ে দেওয়ার জন্য উপরেরগুলির মতো পদ্ধতি প্রয়োগ করবে।


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

2
@ মিচিয়েলভু: যদি কনসেস পদ্ধতির নামকরণ করা সম্ভব হয় না বলে মনে হয় তবে আপনার পদ্ধতিটি যে কাজটি করে তার জন্য কার্যকরী বিমূর্তি তৈরির পরিবর্তে ভুল জিনিসগুলিকে একত্রিত করে (এবং এটি পার্শ্ব প্রতিক্রিয়া সহ বা এটি ছাড়া সত্য)।
ডক ব্রাউন

4

হ্যাঁ, অপ্রত্যাশিত পার্শ্ব প্রতিক্রিয়াগুলি খারাপ বলে উল্লেখ করে এমন বহু উদাহরণের জন্য http://codebetter.com/matthewpodwysocki/2008/04/30/side-effecting-funitions-are-code-smells/ দেখুন ।

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


ওপি "প্রত্যাশিত পার্শ্ব-প্রতিক্রিয়া" হিসাবে বর্ণনা করছে যা আমি বর্ণনা করব। উদাহরণস্বরূপ, কোনও প্রতিনিধি আপনি কোনও ধরণের ইঞ্জিনে পাস করতে পারেন যা তালিকার প্রতিটি উপাদানকে চালিত করে। এটিই মূলত যা ForEach<T>করে।
রবার্ট হার্ভে

@ রবার্টহারভে পদ্ধতিগুলি সঠিকভাবে নামকরণ না করা এবং পার্শ্ব প্রতিক্রিয়াগুলি সনাক্ত করার জন্য কোড পড়ার বিষয়ে অভিযোগগুলি তাদের আশ্বাস-প্রতিক্রিয়া নিশ্চিতভাবে প্রত্যাশিত করে তোলে।
btilly

আমি আপনাকে এটি প্রদান করব। তবে তাত্ত্বিকতাটি হ'ল প্রত্যাশিত সাইট এফেক্টগুলির সাথে সঠিকভাবে নামযুক্ত নথিভুক্ত পদ্ধতিটি সর্বোপরি কোনও বিরোধী-নিদর্শন নাও হতে পারে।
রবার্ট হার্ভে

নিবন্ধন করুন মূলটি হ'ল উল্লেখযোগ্য পার্শ্ব প্রতিক্রিয়াগুলি সম্পর্কে জানার জন্য খুব গুরুত্বপূর্ণ, এবং সাবধানে ডকুমেন্ট করা দরকার (পদ্ধতির নামে)।
btilly

আমি বলব এটি অপ্রত্যাশিত এবং অ-সুস্পষ্ট পার্শ্ব প্রতিক্রিয়াগুলির মিশ্রণ। লিঙ্কের জন্য ধন্যবাদ।
মিশিগেল ভ্যান অস্টারহাট

3

প্রথমত, এটি "রেফারেন্স প্রকৃতি দ্বারা পাস" উপর নির্ভর করে না এটি নির্ভরযোগ্য রেফারেন্স ধরণের বস্তুগুলির উপর নির্ভর করে। অ-কার্যকরী ভাষায় এটি প্রায় সর্বদা ক্ষেত্রে হতে চলেছে।

দ্বিতীয়ত, এটি সমস্যা হোক বা না হোক উভয়র উপর নির্ভর করে এবং বিভিন্ন পদ্ধতিতে পরিবর্তনগুলি কতটা দৃly়তার সাথে একত্রে আবদ্ধ হয় - আপনি যদি ফু-তে কোনও পরিবর্তন করতে ব্যর্থ হন এবং যার ফলে বার ক্রাশ হয়, তবে এটি একটি সমস্যা। অগত্যা কোনও কোডের গন্ধ নয়, তবে এটি ফু বা বার বা কোনও কিছু নিয়ে সমস্যা (সম্ভবত এটি বার হিসাবে এটির ইনপুটটি যাচাই করা উচিত, তবে এটি এমন কিছু হতে পারে যা এটি প্রতিরোধ করা উচিত) invalid

আমি এটি বলব না যে এটি একটি বিরোধী-প্যাটার্নের স্তরে ওঠে, বরং সচেতন হওয়ার মতো কিছু।


2

আমি যুক্তি দেব যে A.Do(Something)সংশোধন somethingsomething.Do()সংশোধন করার মধ্যে সামান্য পার্থক্য রয়েছে something। ইন পারেন যদি, এটা প্রার্থনা পদ্ধতি যে নাম থেকে স্পষ্ট করা কর্তব্য somethingপরিবর্তিত করা হবে না। যদি somethingকোনও প্যারামিটার this, বা পরিবেশের অংশ নির্বিশেষে পদ্ধতির নাম থেকে এটি পরিষ্কার না হয় তবে এটি সংশোধন করা উচিত নয়


1

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

var users = Dependency.Resolve<IGetUsersQuery>().GetAll();

var excludeAdminUsersFilter = new ExcludeAdminUsersFilter();
var filterByAnotherCriteria = new AnotherCriteriaFilter();

excludeAdminUsersFilter.Apply(users);
filterByAnotherCriteria.Apply(users); 

এবং হ্যাঁ, আপনি অন্য পদ্ধতিতে ফিল্টারিং সরিয়ে এটিকে সুন্দর করে তুলতে পারেন, সুতরাং আপনি এর লাইনে কিছু দিয়ে শেষ করবেন:

var users = Dependency.Resolve<IGetUsersQuery>().GetAll();
Filter(users);

যেখানে Filter(users)উপরের ফিল্টারগুলি কার্যকর করা হবে।

আমি এর আগে কোথায় এসেছি ঠিক মনে নেই তবে এটিকে ফিল্টারিং পাইপলাইন হিসাবে উল্লেখ করা হয়েছিল বলে আমি মনে করি।


0

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

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

আপনার সমাধান সম্পর্কে, কিছু পর্যবেক্ষণ:

  • অ্যাপ্লিকেশনগুলি বিভিন্ন দিক থেকে ডিজাইন করা হয়: যখন কোনও বস্তুটি কেবল মান ধরে রাখতে ব্যবহৃত হয়, বা উপাদানগুলির সীমানা পেরিয়ে যায় তখন কীভাবে পরিবর্তন করা যায় তার বিশদটি পূরণ করার পরিবর্তে বস্তুর অভ্যন্তরের বাহ্যিকভাবে পরিবর্তন করা বুদ্ধিমানের কাজ।
  • ক্লোনিং বস্তু মেমরির প্রয়োজনীয়তা bloating হতে, এবং অনেক ক্ষেত্রে বেমানান রাজ্যে সমতুল্য বস্তুর অস্তিত্ব হতে ( Xওঠে Yপরে f()কিন্তু Xআসলে Yসময়গত অসঙ্গতি,) এবং সম্ভবত।

আপনি যে সমস্যাটি সমাধান করার চেষ্টা করছেন সেটি একটি বৈধ সমস্যা; যাইহোক, এমনকি অত্যধিক অতিরিক্ত কাজটি সম্পন্ন করার পরেও, সমস্যাটি নিষ্পত্তি হয়, সমাধান হয় না।


2
যদি আপনি ওপির প্রশ্নের সাথে আপনার পর্যবেক্ষণটি সম্পর্কিত করেন তবে এটি আরও ভাল উত্তর হবে। যেমনটি, এটি একটি উত্তরের চেয়ে বেশি মন্তব্য।
রবার্ট হার্ভে

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