আপনি কি সর্বদা এই জাতীয় ক্ষেত্রে একটি ফাংশন মধ্যে প্রয়োজন খালি সর্বনিম্ন তথ্য পাস করা উচিত?


81

ধরা যাক আমার একটি ফাংশন রয়েছে IsAdminযা ব্যবহারকারী একজন প্রশাসক কিনা তা যাচাই করে। আসুন আমরা এটাও বলি যে প্রশাসক চেকিং কোনও আইনের বিপরীতে (গুরুত্বপূর্ণ নয়) এর সাথে ব্যবহারকারীর আইডি, নাম এবং পাসওয়ার্ডের সাথে মিলিয়ে করা হয়।

আমার মাথায় তখন এর জন্য দুটি কার্য সম্পাদনের স্বাক্ষর রয়েছে:

public bool IsAdmin(User user);
public bool IsAdmin(int id, string name, string password);

আমি প্রায়শই দ্বিতীয় ধরণের স্বাক্ষরের জন্য যাই, এই ভেবে:

  • ফাংশনের স্বাক্ষর পাঠককে আরও অনেক তথ্য দেয়
  • ফাংশনের ভিতরে থাকা যুক্তিটির Userক্লাস সম্পর্কে জানতে হবে না
  • এটি সাধারণত ফাংশনের অভ্যন্তরে কিছুটা কম কোডের ফলাফল করে

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

আমি উভয় শৈলীর জন্য যে কোনও যুক্তি, পাশাপাশি আপনার দেওয়া সাধারণ পর্যবেক্ষণের প্রশংসা করব।

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


40
অফ-টপিক: কৌতূহলের বাইরে, কোনও ব্যবহারকারীর "প্রশাসক" স্থিতি কেন তাদের পাসওয়ার্ডের উপর নির্ভর করে?
stakx


68
@ syb0rg ঠিক আছে, তিনি ভাষাটি নির্দিষ্ট করেননি তাই আমি মনে করি এটি নির্দিষ্ট করে বলা উচিত যে তিনি কোনও নির্দিষ্ট ভাষার সম্মেলন লঙ্ঘন করছেন tell
চৌম্বকীয়

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

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

উত্তর:


123

আমি ব্যক্তিগতভাবে ন্যায়বিচারের প্রথম পদ্ধতিটি পছন্দ করি IsAdmin(User user)

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

এটি সম্ভবত আরও সুরক্ষিত যেহেতু আপনি কোনও বিজ্ঞাপনী কিনা প্রশাসনের কোনও সম্পত্তি বা অ্যাডমিন কিনা বা পাসওয়ার্ডের সম্পত্তি জুড়ে সর্বত্র পাস করার জন্য কোন বৈশিষ্ট্য নির্ধারণ করে তা বিজ্ঞাপন না দিচ্ছেন। এবং সিরিয়ান একটি ভাল পয়েন্ট দেয় যে যখন আপনার / এর সাথে idমেলে না তখন কী ঘটে ?namepassword

কোনও ফাংশনের অভ্যন্তরে কোডের দৈর্ঘ্যটি পদ্ধতিটি কার্যকরভাবে সরবরাহ করে তা বিবেচনা করা উচিত না এবং আমি সহায়ক পদ্ধতির কোডের চেয়ে আরও ছোট এবং সহজ অ্যাপ্লিকেশন কোডটি চাইতাম।


3
আমি মনে করি রিফ্যাক্টরিং ইস্যুটি খুব ভাল একটি বিষয় - আপনাকে ধন্যবাদ।
Anders Arpi

1
আপনি না করলে আমি পদ্ধতিটি স্বাক্ষর যুক্তি করতে যাচ্ছিলাম। এটি বিশেষত সহায়ক যখন আপনার পদ্ধতিতে প্রচুর নির্ভরতা থাকে যা অন্যান্য প্রোগ্রামারদের দ্বারা পরিচালিত হয়। এটি মানুষকে একে অপরের পথ থেকে দূরে রাখতে সহায়তা করে। +1
jmort253

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

আদিম আবেগ বিরোধী প্যাটার্ন ইউনিট পরীক্ষার জন্য ভয়ঙ্কর হতে পারে।
স্যামুয়েল

82

প্রথম স্বাক্ষরটি উচ্চতর কারণ এটি Userঅবজেক্টটিতেই ব্যবহারকারী-সম্পর্কিত যুক্তির এনক্যাপসুলেশনকে অনুমতি দেয় । আপনার কোড বেস সম্পর্কে প্রসারিত "আইডি, নাম, পাসওয়ার্ড" টিপল তৈরির পক্ষে যুক্তিযুক্ত হওয়া সুবিধাজনক নয়। তদ্ব্যতীত, এটি isAdminফাংশনটিকে জটিল করে তোলে: উদাহরণস্বরূপ, কেউ যদি কোনওটির সাথে idমেলে না এমন পাস করে তবে কী ঘটে name? আপনি যদি পরীক্ষা করতে চান যে কোনও প্রদত্ত ব্যবহারকারীর এমন প্রসঙ্গ থেকে প্রশাসক আছেন যেখানে আপনার পাসওয়ার্ডটি আপনার জানা উচিত নয় ?

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


45
আপনার যুক্তি অনুসরণ, user.IsAdmin()অনেক ভাল না?
অ্যান্ডার্স আরপী

13
হ্যাঁ একেবারে.
অ্যাথাস্টার

6
@ অ্যান্ডারসহলমস্ট্রম এটি নির্ভর করে, ব্যবহারকারী যদি সাধারণভাবে একজন প্রশাসক হন বা আপনি যে বর্তমান পৃষ্ঠা / ফর্মটিতে আছেন তার জন্য কেবল প্রশাসক হন তবে আপনি এটি পরীক্ষা করছেন? যদি সাধারণভাবে হয় তবে হ্যাঁ এটি আরও ভাল হবে তবে আপনি যদি কেবল IsAdminকোনও নির্দিষ্ট ফর্ম বা ফাংশনের জন্য পরীক্ষা করে থাকেন তবে এটি ব্যবহারকারীর সাথে সম্পর্কিত নয়
রাচেল

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

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

65

প্রথমটি, তবে (কেবল) অন্যরা যে কারণে দিয়েছে তা নয়।

public bool IsAdmin(User user);

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

public bool IsAdmin(int id, string name, string password);

এখানে, কোনও int এবং দুটি স্ট্রিং করবে do নাম এবং পাসওয়ার্ড স্থানান্তর করতে আপনাকে কী বাধা দেয়? দ্বিতীয়টি হ'ল আরও কাজ করা এবং ত্রুটির জন্য আরও সুযোগের সুযোগ দেয়।

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

user.isAdmin();

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

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


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

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

2
@ গ্লেনপিটারসন: আপনি কি ইচ্ছাকৃতভাবে আমাকে ভুল বুঝছেন? আমি যখন ব্যবহারকারী বলি, আমি অবশ্যই ব্যবহারকারী শ্রেণি বোঝায়।
মার্জন ভেনেমা

2
@ গ্লেনপিটারসন পুরোপুরি বিষয় বন্ধ করেছেন, তবে একাধিক রাউন্ড হ্যাশিং এবং ক্রিপ্টোগ্রাফিক ফাংশন তথ্যকে দুর্বল করে দেবে।
গুড্ডর

3
@ মারজানভেনেমা: আমি ইচ্ছাকৃতভাবে কঠিন হচ্ছি না। আমি মনে করি আমাদের খুব ভিন্ন দৃষ্টিভঙ্গি রয়েছে এবং আমি আপনার আরও ভাল করে বুঝতে চাই। আমি একটি নতুন প্রশ্ন খুলেছি যেখানে এটি আরও ভালভাবে আলোচিত হতে পারে: প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জার
216443/…

6

আপনার পছন্দের ভাষা যদি মান অনুসারে কাঠামো পাস না করে তবে (User user)বৈকল্পিক আরও ভাল বলে মনে হয়। যদি কোনও দিন আপনি ব্যবহারকারীর নামটি স্ক্র্যাপ করার সিদ্ধান্ত নেন এবং কেবল ব্যবহারকারীকে সনাক্ত করতে আইডি / পাসওয়ার্ড ব্যবহার করেন?

এছাড়াও, এই পদ্ধতির অনিবার্যভাবে দীর্ঘ এবং ওভারব্লাউন পদ্ধতি কল বা অসঙ্গতি বাড়ে। 3 টি আর্গুমেন্ট পাস করা কি ঠিক আছে? কিভাবে 5? বা 6? কেন এটি ভাবুন, যদি কোনও সামগ্রীর পাস করা সম্পদের দিক থেকে সস্তা (সম্ভবত 3 টি যুক্তি পাস করার চেয়েও কম)?

এবং আমি (ধরণের) একমত নই যে দ্বিতীয় পদ্ধতিটি পাঠককে আরও তথ্য দেয় - স্বজ্ঞাতভাবে, পদ্ধতি কলটি "ব্যবহারকারীর অ্যাডমিনের অধিকার রয়েছে কিনা" জিজ্ঞাসা করছে, "প্রদত্ত আইডি / নাম / পাসওয়ার্ডের সমন্বয় প্রশাসকের অধিকার রয়েছে কিনা" তা নয়।

সুতরাং, Userঅবজেক্টটি পাস না করা যদি না কোনও বৃহত কাঠামো অনুলিপি করে, তবে প্রথম পদ্ধতির বিষয়টি আমার কাছে আরও পরিষ্কার এবং আরও যৌক্তিক।


3

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

যদি পরবর্তী সময়ে আমাকে চেকিংয়ের নিয়মটি পরিবর্তন করতে হয়, আমি কেবলমাত্র একটি নতুন ব্যক্তিগত ফাংশন লিখব একটি নতুন স্বাক্ষর সহ বহিরাগত দ্বারা ডাকা।

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

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

অন্য কথায় আপনি যদি একটি ডাটাবেস নিয়ে কাজ করে থাকেন তবে ব্যবহারকারী একটি রেকর্ড হতে পারে, যখন আইডি, পাসওয়ার্ড এবং লগইন সেই রেকর্ডের ক্ষেত্র হবে।


আমি ব্যক্তিগত পদ্ধতির কারণ দেখছি না। দুজনেই রক্ষণাবেক্ষণ কেন? যদি ব্যক্তিগত পদ্ধতিতে বিভিন্ন যুক্তির প্রয়োজন হয় তবে আপনাকে সর্বজনীন পরিবর্তন করতে হবে। এবং আপনি এটি সর্বজনীন মাধ্যমে পরীক্ষা করা হবে। এবং না এটি পরে কখনও কখনও আপনার উভয় প্রয়োজন যে স্বাভাবিক হয় না। আপনি এখানে অনুমান করছেন - ইয়াগনি
পাইওটর পেরাক

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

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

অন্য শব্দ: আমি অবশ্যই বাহ্যিকের মাধ্যমে অভ্যন্তরীণ পদ্ধতিটি এককভাবে পরীক্ষা করব না। এটা খারাপ পরীক্ষা অনুশীলন।
ক্রিস

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

3

পদ্ধতিগুলিতে ক্লাসগুলি (রেফারেন্সের ধরণ) প্রেরণের একটি নেতিবাচক পয়েন্ট রয়েছে এবং তা হ'ল গণ-কার্য-নির্ধারণী ক্ষতিগ্রস্থতা । ভাবুন যে IsAdmin(User user)পদ্ধতির পরিবর্তে আমার কাছে UpdateUser(User user)পদ্ধতি আছে।

যদি Userক্লাসে একটি বুলিয়ান সম্পত্তি বলা হয় IsAdminএবং আমি যদি আমার পদ্ধতির প্রয়োগের সময় এটি পরীক্ষা না করি তবে আমি ভর-কার্যভারের পক্ষে ঝুঁকিপূর্ণ। 2012 সালে এই খুব স্বাক্ষর দ্বারা গিটহাব আক্রমণ করেছিল।


2

আমি এই পদ্ধতির সাথে যেতে হবে:

public bool IsAdmin(this IUser user) { /* ... */ }

public class User: IUser { /* ... */ }

public interface IUser
{
    string Username {get;}
    string Password {get;}
    IID Id {get;}
}
  • এই ফাংশনটির জন্য প্যারামিটার হিসাবে ইন্টারফেস টাইপ ব্যবহার করা আপনাকে ব্যবহারকারীর অবজেক্টগুলিতে পাস করতে, পরীক্ষার জন্য মক ব্যবহারকারীর অবজেক্টগুলি সংজ্ঞায়িত করতে দেয় এবং আপনাকে এই ফাংশনটির ব্যবহার এবং রক্ষণাবেক্ষণ উভয় ক্ষেত্রেই আরও নমনীয়তা দেয়।

  • আমি thisফাংশনটিকে সমস্ত আইউজার ক্লাসের এক্সটেনশন পদ্ধতিতে তৈরি করতে কীওয়ার্ডটিও যুক্ত করেছি ; এইভাবে আপনি কোডটিকে আরও OO বন্ধুত্বপূর্ণ উপায়ে লিখতে পারেন এবং এই ফাংশনটি লিনক ক্যোয়ারিতে ব্যবহার করতে পারেন। সরল এখনও আইউজার এবং ব্যবহারকারীর মধ্যে এই ফাংশনটি সংজ্ঞায়িত করা হবে, তবে আমি ধরে নিই যে আপনি কেন এই পদ্ধতিটিকে এই শ্রেণীর বাইরে রাখার সিদ্ধান্ত নিয়েছিলেন এমন কোনও কারণ আছে?

  • আমি এর IIDপরিবর্তে কাস্টম ইন্টারফেস ব্যবহার করি যা এটি intআপনাকে আপনার আইডির বৈশিষ্ট্যগুলি নতুন করে সংজ্ঞায়িত করতে দেয়; যেমন আপনি কি কখনো থেকে পরিবর্তন করতে হবে উচিত intকাছে long, Guid, নাকি অন্য কিছু। এটি সম্ভবত ওভারকিল, তবে জিনিসকে নমনীয় করে তোলার চেষ্টা করা সর্বদা ভাল যে আপনি প্রাথমিক সিদ্ধান্তগুলিতে লক নন।

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


3
আইউজারটি এখানে অকেজো এবং কেবল জটিলতা যুক্ত করে। আপনি কেন পরীক্ষাগুলিতে প্রকৃত ব্যবহারকারী ব্যবহার করতে পারেন না তা আমি দেখতে পাচ্ছি না।
পাইওটর পেরাক

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

@ পেরি একটি বাস্তব ব্যবহারকারী শ্রেণি তৈরি করা জটিল হতে পারে, একটি ইন্টারফেস নেওয়া আপনাকে এটিকে উপহাস করার অনুমতি দেয় যাতে আপনি আপনার পরীক্ষাগুলি সহজ রাখতে পারেন
জে.কে.

@ জনলবেশন: ইয়াগনি !!!
পাইওটার পেরাক

@jk .: যদি এটা ব্যবহারকারী গড়ে তুলতে কঠিন তারপর কিছু অস্বাভাবিক হয়
পাযত্র Perak- এর

1

দাবিত্যাগ:

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

আমিও এর user.isAdmin()সমতুল্য বিবেচনা করি IsAdmin(User user)। এটি আপনার পছন্দ করার জন্য পছন্দ।

উত্তর:

আমার সুপারিশটি কেবলমাত্র ব্যবহারকারীদের জন্য:

public bool IsAdmin(User user);

বা উভয়, এর লাইন বরাবর ব্যবহার করুন:

public bool IsAdmin(User user); // calls the private method below
private bool IsAdmin(int id, string name, string password);

পাবলিক পদ্ধতির কারণগুলি:

সর্বজনীন পদ্ধতিগুলি লেখার সময় এগুলি কীভাবে ব্যবহৃত হবে সে সম্পর্কে চিন্তা করা ভাল।

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

ব্যক্তিগত পদ্ধতির কারণগুলি:

প্রয়োজনীয় প্যারামিটারগুলির সর্বনিম্ন সেটটি প্রাপ্ত ব্যক্তিগত পদ্ধতিটি কখনও কখনও ভাল জিনিস হতে পারে। কখনও কখনও এত কিছু না।

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

public bool IsAdmin(Localuser user); // Just call private method
public bool IsAdmin(RemoteUser user); // Check if setting is on, then call private method
private bool IsAdmin(int id, string name, string password);

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

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


0
public bool IsAdmin(int id, string name, string password);

তালিকাভুক্ত কারণে খারাপ। তার মানে এই নয়

public bool IsAdmin(User user);

স্বয়ংক্রিয়ভাবে ভাল। বিশেষ করে, তাহলে ব্যবহারকারী একটি বস্তু মত পদ্ধতি হচ্ছে: getOrders(), getFriends(), getAdresses(), ...

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

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