এর মতো কোডটি কি "ট্রেনের ধ্বংসস্তূপ" (ডেমিটারের আইন লঙ্ঘন করে)?


23

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

service.setLocation(this.configuration.getLocation().toString());

এই ক্ষেত্রে, serviceএকটি পরিচিত ধরনের একটি দৃষ্টান্ত পরিবর্তনশীল, পদ্ধতি মধ্যে ঘোষিত হয়। this.configurationক্লাস কন্সট্রাক্টরের কাছে পৌঁছে দেওয়া থেকে আসে এবং এটি কোনও শ্রেণিবদ্ধ একটি নির্দিষ্ট ইন্টারফেস (যা জনসাধারণের getLocation()পদ্ধতিতে আদেশ দেয় ) প্রয়োগ করে of সুতরাং, অভিব্যক্তিটির রিটার্নের ধরণটি this.configuration.getLocation()জানা যায়; বিশেষভাবে এই ক্ষেত্রে, এটি একটি হল java.net.URLযেহেতু, service.setLocation()একটি চায় String। স্ট্রিং এবং ইউআরএল দুই প্রকারের সরাসরি সামঞ্জস্যপূর্ণ না হওয়ায় বৃত্তাকার ছিদ্রের বর্গক্ষেত্রের পেগ ফিট করার জন্য কোনও ধরণের রূপান্তর প্রয়োজন।

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

উপরোক্ত মত কলগুলি তালিকাভুক্ত প্রতিবন্ধকতাগুলি দেখিয়ে নিরুৎসাহিত করা বা নিষেধ করা উচিত কেন এর কোন বৈধ যুক্তি আছে? নাকি আমি শুধু মাত্রাতিরিক্ত নীটপিকি হয়ে যাচ্ছি?

যদি আমি এমন কোনও পদ্ধতি প্রয়োগ করি URLToString()যা কেবল toString()কোনও URLবস্তুর উপর কল করে (যেমনটি ফিরে আসে getLocation()) এটি প্যারামিটার হিসাবে প্রেরণ করে এবং ফলাফলটি ফিরে আসে, getLocation()ঠিক একই ফলাফলটি অর্জনের জন্য আমি কলটি মোড়ানো করতে পারতাম ; কার্যকরভাবে, আমি কেবল রূপান্তরকে এক ধাপ বাইরে নিয়ে যেতে চাই। এটি কি কোনওভাবে এটি গ্রহণযোগ্য করে তুলবে? (এটি স্বজ্ঞাতভাবে আমার কাছে মনে হয়েছে যে এটি কোনওভাবেই কোনও পার্থক্য তৈরি করা উচিত নয়, যেহেতু এটি সমস্ত কিছুকে কিছুটা ঘুরিয়ে দেয় However তবে, ল অফ অফ ডিমেটারের চিঠিটি উদ্ধৃত হিসাবে দেওয়া, এটি গ্রহণযোগ্য হবে, যেহেতু আমি তারপরে কোনও ফাংশনের প্যারামিটারে সরাসরি পরিচালনা করা হবে))

এটি যদি toString()কোনও স্ট্যান্ডার্ড ধরণের কল করার চেয়ে কিছুটা বেশি বিদেশী কিছু নিয়ে আসে তবে কি কোনও পার্থক্য হবে ?

উত্তর দেওয়ার সময়, মনে রাখবেন যে পরিবর্তনশীল যে ধরণের হয় তার আচরণ বা এপিআই serviceপরিবর্তন করা কার্যকর নয়। এছাড়াও, তর্কের খাতিরে, বলি যে রিটার্নের ধরণের পরিবর্তন getLocation()করাও অযৌক্তিক।

উত্তর:


34

এখানে সমস্যা হল স্বাক্ষর setLocation। এটি কঠোরভাবে টাইপ করা হয়

বিস্তারিত বলার জন্য: এটি কেন আশা করবে String? একটি Stringপ্রতিনিধিত্ব করে পাঠগত তথ্য যে কোন ধরণের । এটি একটি বৈধ অবস্থান ছাড়াও সম্ভাব্য কিছু হতে পারে।

আসলে, এটি একটি প্রশ্ন উত্থাপন: একটি অবস্থান কি? আপনার কোডটি না দেখে আমি কীভাবে জানব? যদি এটির URLচেয়ে একটি হত তবে এই পদ্ধতিটি কী প্রত্যাশা করে তা সম্পর্কে আমি আরও অনেক কিছু জানতে পারি।
এটি এটি একটি কাস্টম শ্রেণি হতে আরও বোধগম্য হবে Location। ঠিক আছে, আমি প্রথমে জানতাম না, এটি কী, তবে কোনও সময়ে (সম্ভবত লেখার আগে this.configuration.getLocation()আমি এই পদ্ধতিটি কী ফিরে আসে তা নির্ধারণের জন্য এক মিনিট সময় নেব)।
মঞ্জুর, উভয় ক্ষেত্রেই আমার বোঝার জন্য আরও কিছু জায়গা প্রয়োজন, যা প্রত্যাশিত। তবে পরবর্তী ক্ষেত্রে, যদি আমি বুঝতে পারি, একটি Locationকী, আমি আপনার এপিআই ব্যবহার করতে পারি, পূর্ববর্তী ক্ষেত্রে, যদি আমি বুঝতে পারি, একটি কী Stringকী (যা প্রত্যাশা করা যেতে পারে), তবে এখনও আমি জানি না যে আপনার এপিআই কী প্রত্যাশা করে।

অসম্ভব দৃশ্যে, যে অবস্থানটি হ'ল ধরণের পাঠ্যগত ডেটা হ'ল আমি এটি কোনও ধরণের ডেটাতে পুনরায় ব্যাখ্যা করব, এতে একটি পাঠ্য উপস্থাপনা রয়েছে । এই পদ্ধতিটি আপনার কোডের ক্লায়েন্টদের কাছ থেকে বিশ্বাসের এক ঝাঁকুনির দাবি সত্ত্বেও, Objectএর একটি toStringপদ্ধতি রয়েছে, তা আপনি দিয়েছিলেন that

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

যে কেউ তর্ক করতে পারে, toStringজাভা এর অনাবশ্যক দাবি দ্বারা উত্পন্ন গোলমালের চেয়ে শেষ কলটি কম কল। আপনি কোনও পদ্ধতি কল করছেন, যে কোনও জাভা অবজেক্ট রয়েছে, সুতরাং আপনি আসলে "দূরবর্তী ইউনিট" সম্পর্কে কোনও জ্ঞান এনকোড করবেন না এবং এর ফলে ন্যূনতম জ্ঞানের নীতি লঙ্ঘন করবেন না। কোনও উপায় নেই, যাই হোক না কেন getLocationফিরে আসুক, এটির কোনও toStringপদ্ধতি নেই।

তবে দয়া করে, স্ট্রিংগুলি ব্যবহার করবেন না, যদি না সেগুলি সত্যই সবচেয়ে স্বাভাবিক পছন্দ হয় (বা আপনি যদি কোন ভাষা ব্যবহার না করেন, তবে সেখানে এনাম থাকে না ... সেখানে থাকতেন না)।


আমি আপনার সাথে একমত হতে চাই, কিন্তু তিনি ইতিমধ্যে বলেছেন যে সে পরিষেবা API এ সংশোধন করতে পারে না।
21:48

1
@ ঝকিং: তিনি বলেননি যে তিনি পারবেন না। তিনি বলেছিলেন এটি অযৌক্তিক। আমি একমত না কোডটিতে সেরা অনুশীলনগুলি প্রয়োগ করার চেষ্টা করা হয়েছে যা এপিআই ডিজাইনের ত্রুটিগুলি ঘিরে কাজ করে যদি সত্যিকার অর্থে যদি এই জাতীয় কাজের একমাত্র সম্ভাব্য বিকল্প হয়। তবে এখানে সরাসরি API সেট করা সেরা বিকল্প। ঘাটতিগুলি অপসারণ করা সবসময় তাদের চারপাশে কাজ করা ভাল।
back2dos

যাইহোক +1 এর জন্য "
জাফির বিবরণের

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

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

21

ডেমিটারের আইন হ'ল ডিজাইনের গাইডলাইন, ধর্মীয়ভাবে অনুসরণ করা আইন নয় not

আপনি যদি মনে করেন যে আপনার ক্লাসগুলি লাইনটির সাথে কিছু ভুল না হওয়ার চেয়ে যথেষ্ট ডিকোপলড রয়েছে this.configuration.getLocation()বিশেষত যদি আপনি যেমন বলে থাকেন, এটিপিআইয়ের অন্যান্য অংশগুলি পরিবর্তন করা অবৈধ ।

আমি নিশ্চিত যে ক্লায়েন্ট পুরোপুরি খুশি হ'ল এমনকি যদি আপনি ডেমিটারের আইনটিকে টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো করে দেবেন। কোনটি খারাপ সফ্টওয়্যার বানানোর অজুহাত নয়, তবে সফ্টওয়্যার বিকাশ করার সময় ব্যবহারিক হওয়ার জন্য একটি অনুস্মারক।


1
যেহেতু this.configurationএকটি পরিচিত ইন্টারফেসের এক ধরণের উদাহরণস্বরূপ পরিবর্তনশীল, তাই কোনও ইন্টারফেস দ্বারা সংজ্ঞায়িত এমন কোনও পদ্ধতিতে কল করা একটি কঠোর ব্যাখ্যা অনুসারে এমনকি সূক্ষ্ম বলে মনে হয়। হ্যাঁ, আমি জানি যে এটি একটি গাইডলাইন, ঠিক যেমন KISS, SOLID, YAGNI এবং এর মতো। সাধারণ সফ্টওয়্যার বিকাশে যদি কোনও "আইন" (আইনগত দিক থেকে) থাকে তবে খুব কমই রয়েছে।
একটি সিভিএন

4
ব্যবহারিক হওয়ার জন্য +1 ;-)
ট্রেব

1
আমি মনে করি না ডেমেন্টারের আইন এমনকি এই জাতীয় ক্ষেত্রে প্রয়োগ করা উচিত - কনফিগারেশনটি মূলত একটি ধারক। প্রতিটি এপিআইতে আমি অভ্যন্তরীণ পাত্রে সন্ধানের সাথে কাজ করেছি তা স্বাভাবিক এবং প্রত্যাশিত আচরণ।
লরেন পেচেল

2

আমি এই জাতীয় কোডটি না লিখতে ভাবতে পারি তবে তা যদি this.configuration.getLocation()শূন্য হয়? এটি আপনার আশেপাশের কোড এবং এই কোডটি ব্যবহার করে দর্শকের জন্য লক্ষ্য নির্ভর করে depends তবে মার্কো যেমন বলেছিলেন - ডেমিটারের আইনটি থাম্বের একটি নিয়ম - এটি অনুসরণ করা ভাল, তবে অযথা এইভাবে আপনার পিঠটি ভাঙ্গবেন না।


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

2

কঠোরভাবে ডেমিটারের আইন অনুসরণ করার অর্থ হ'ল আপনার কনফিগারেশন অবজেক্টে কোনও পদ্ধতি প্রয়োগ করা উচিত:

function getLocationAsString() {
  return getLocation().toString();
}

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


1
এটি এখানে একই পরামর্শ দেওয়া হয়েছে: c2.com/cgi/wiki?TrainWreck "এমন একটি পদ্ধতি তৈরি করুন যা পছন্দসই আচরণের প্রতিনিধিত্ব করে এবং ক্লায়েন্টকে কী করতে হবে তা বলে। এটি" বলুন, জিজ্ঞাসা করবেন না "নীতিটি অনুসরণ করে।"
হেলটনবাইকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.