কোনও পদ্ধতির যুক্তির নামকরণের জন্য কোনও ভেরিয়েবলের সংজ্ঞা দেওয়া কি একটি ভাল অনুশীলন?


73

পাঠযোগ্যতার খাতিরে আমি প্রায়শই নিজেকে নীচের কোডের মতো ফাংশনগুলিতে কল করার সময় অস্থায়ী পরিবর্তনগুলি সংজ্ঞায়িত করতে দেখি

var preventUndo = true;
doSomething(preventUndo);

এটির সংক্ষিপ্ত সংস্করণটি হ'ল,

doSomething(true);

কিন্তু আমি কোডটিতে ফিরে এলে আমি প্রায়শই অবাক হই যে কী trueবোঝায়। এই ধরণের কনড্রামের জন্য কোনও কনভেনশন রয়েছে?


5
আপনি কি কোনও ধরণের আইডিই ব্যবহার করেন? বেশিরভাগের কাছে আপনি যে ফাংশনটি কল করছেন তার পরামিতিগুলি কী তা নির্দেশ করার কিছু উপায় থাকবে যা এটি করার প্রয়োজনীয়তা কিছুটা বাতিল করে দেয়।
ম্যাথু শার্লে

4
আমি কোনও আইডিই ব্যবহার করি না, তবে তারপরেও আমি মনে করি ইঙ্গিতটির জন্য কোনও ধরণের ক্রিয়া প্রয়োজন হবে (মাউসওভার বা লাইনে চলে যাওয়া) require আমার কোডটি এটি দেখে কেবল কী করছে তা আমি জানতে চাই।
পদ্ধতিটি

11
ভাষা যদি এটি সমর্থন করে তবে আপনি একটি গণনা ব্যবহার করতে পারেন যেমনdoSomething( Undo.PREVENT )
জেমস পি।

4
তবে আপনি সংজ্ঞা দিতে পারেন Undo = { PREVENT = true, DONT_PREVENT = false }। তবে জাভাস্ক্রিপ্টে, কনভেনশনটি এটির মতো করাতে হবে: function myFunction( mandatoryArg1, mandatoryArg2, otherArgs ) { /*...*/ }এবং তারপরে myFunction( 1, 2, { option1: true, option2: false } )
xavierm02

6
এটি অবশ্যই ভাষার উপর নির্ভর করে। যদি এটি অজগর হয়, উদাহরণস্বরূপ, আমি কেবল কীওয়ার্ড আর্গুমেন্টগুলি ব্যবহার করার পরামর্শ দেব, উদাহরণস্বরূপdoSomething(preventUndo=True)
জোয়েল করনেট

উত্তর:


117

চলক ব্যাখ্যা

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

ভাল মানের কোড পাঠকের উদ্দেশ্যে অভিপ্রায় যোগাযোগ করে; এবং একজন পেশাদার বিকাশকারী হিসাবে পঠনযোগ্যতা এবং রক্ষণাবেক্ষণ আপনার # 1 লক্ষ্য goals

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

editButton.Enabled = (_grid.SelectedRow != null && ((Person)_grid.SelectedRow).Status == PersonStatus.Active);

বনাম সামান্য দীর্ঘ, তবে তর্কযোগ্যভাবে পরিষ্কার:

bool personIsSelected = (_grid.SelectedRow != null);
bool selectedPersonIsEditable = (personIsSelected && ((Person)_grid.SelectedRow).Status == PersonStatus.Active)
editButton.Enabled = (personIsSelected && selectedPersonIsEditable);

বুলিয়ান প্যারামিটার

আপনার উদাহরণটি হাইলাইট করে যে এপিআইগুলিতে বুলিয়ানগুলি প্রায়শই একটি খারাপ ধারণা - কলিংয়ের দিকে, তারা কী ঘটছে তা ব্যাখ্যা করার জন্য কিছুই করে না। বিবেচনা:

ParseFolder(true, false);

এই পরামিতিগুলির অর্থ কী তা আপনাকে সন্ধান করতে হবে; যদি তারা enums হয়, এটি অনেক বেশি পরিষ্কার হবে:

ParseFolder(ParseBehaviour.Recursive, CompatibilityOption.Strict);

সম্পাদনা:

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


28
আপনি নামকরণকৃত প্যারামিটারগুলি (.NET ফ্রেমওয়ার্কের নামযুক্ত যুক্তি) ব্যবহার না করলে, সেক্ষেত্রে doSomething(preventUndo: true);যথেষ্ট পরিস্কার। এছাড়াও, আপনার এপিআই-তে প্রতিটি বুলিয়ানের জন্য এনাম তৈরি করছেন? সিরিয়াসলি?
আর্সেনী মোরজেনকো

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

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

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

3
এই কারণেই এমএস প্রতিটি সংস্করণে তারা যুক্ত করা সমস্ত নতুন স্টাফের সেই চমৎকার সংক্ষিপ্তসারগুলি প্রকাশ করে, আমি মনে করি না যে এটি প্রতি কয়েক বছর পর পর যে কোনও একটি পড়তে প্রচুর কাজ তৈরি করে: এমএসডিএন.মাইক্রোসফটকম
সি কে

43

আপনার প্রয়োজন নেই কোডটি লিখবেন না।

যদি আপনার doSomething(true)বুঝতে অসুবিধা হয় তবে আপনার একটি মন্তব্য করা উচিত:

// Do something and prevent the undo.
doSomething(true);

অথবা, ভাষা যদি এটি সমর্থন করে তবে পরামিতিটির নাম যুক্ত করুন:

doSomething(preventUndo: true);

অন্যথায়, আপনাকে বলা পদ্ধতির স্বাক্ষর দিতে আপনার আইডিইয়ের উপর নির্ভর করুন:

এখানে চিত্র বর্ণনা লিখুন

ক্ষেত্রে যেখানে এটি দরকারী

অতিরিক্ত ভেরিয়েবল স্থাপন কার্যকর হতে পারে:

  1. ডিবাগিং উদ্দেশ্যে:

    var productId = this.Data.GetLastProductId();
    this.Data.AddToCart(productId);
    

    একই কোডটি একটি লাইনে লেখা যেতে পারে, তবে আপনি যদি পণ্যটি আইডি সঠিক কিনা তা দেখতে কার্টে একটি পণ্য যুক্ত করার আগে যদি ব্রেকআপপয়েন্ট রাখতে চান তবে একের পরিবর্তে দুটি লাইন লিখাই ভাল ধারণা।

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

    // Even with indentation, this is unreadable.
    var doSomething(
        isSomethingElse ? 0 : this.getAValue(),
        this.getAnotherOne() ?? this.default,
        (a + b + c + d + e) * f,
        this.hello ? this.world : (this.hello2 ? this.world2 : -1));
    
  3. যদি কোনও প্যারামিটারের মূল্যায়ন খুব জটিল হয়। আমি দেখেছি এমন একটি কোডের উদাহরণ:

    // Wouldn't it be easier to have several if/else's (maybe even in a separate method)?
    do(something ? (hello ? world : -1) : (programmers ? stackexchange : (com ? -1 : 0)));
    

অন্য ক্ষেত্রে কেন হয় না?

আপনি সাধারণ ক্ষেত্রে অতিরিক্ত ভেরিয়েবল তৈরি করবেন না কেন?

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

  2. তবে আপনি প্যারামিটারের নামটি পরিবর্তনশীলটিকে যে নামটি দিয়েছিলেন তা বিচ্ছিন্ন করার ঝুঁকির কারণে।

    উদাহরণ:

    আসুন বলি যে মূল কোডটি হ'ল:

    void doSomething(bool preventUndo)
    {
        // Does something very interesting.
        undoHistory.removeLast();
    }
    
    // Later in code:
    var preventUndo = true;
    doSomething(preventUndo);
    

    পরবর্তীতে, কোনও বিকাশকারী doSomethingনোটিশে কাজ করছেন যা সম্প্রতি, পূর্বাবস্থায় ফিরানো ইতিহাস দুটি নতুন পদ্ধতি চালু করেছে:

    undoHistory.clearAll() { ... }
    undoHistory.disable() { ... }
    

    এখন, preventUndoখুব পরিষ্কার মনে হচ্ছে না। এর অর্থ কি কেবলমাত্র শেষ কর্মটি প্রতিরোধ করা হবে? অথবা এর অর্থ হ'ল ব্যবহারকারী আর আর পূর্বে ফিরিয়ে আনতে পারবেন না? নাকি পূর্বাবস্থার ইতিহাস সাফ হয়ে যাবে? পরিষ্কার নামগুলি হবে:

    doSomething(bool hideLastUndo) { ... }
    doSomething(bool removeAllUndo) { ... }
    doSomething(bool disableUndoFeature) { ... }
    

    সুতরাং এখন আপনার আছে:

    void doSomething(bool hideLastUndo)
    {
        // Does something very interesting.
        undoHistory.removeLast();
    }
    
    // Later in code, very error prone, while the signature of the method is clear:
    var preventUndo = true;
    doSomething(preventUndo);
    

Enums সম্পর্কে কি?

কিছু অন্যান্য ব্যক্তি এনাম ব্যবহারের পরামর্শ দিয়েছেন। এটি তাত্ক্ষণিক সমস্যাটি সমাধান করার সময় এটি একটি বড় সমস্যা তৈরি করে। এর কটাক্ষপাত করা যাক:

enum undoPrevention
{
    keepInHistory,
    prevent,
}

void doSomething(undoPrevention preventUndo)
{
    doTheJob();
    if (preventUndo == undoPrevention.prevent)
    {
        this.undoHistory.discardLastEntry();
    }
}

doSomething(undoPrevention.prevent);

এতে সমস্যা:

  1. এটি অনেক বেশি কোড। if (preventUndo == undoPrevention.prevent)? সিরিয়াসলি ?! আমি ifপ্রতিবার এ জাতীয় গুলি লিখতে চাই না ।

  2. এনামে কোনও উপাদান যুক্ত করা খুব পরে লোভনীয়, যদি আমি একই এনামটি অন্য কোথাও ব্যবহার করি। যদি আমি এটির মতো এটি সংশোধন করি তবে:

    enum undoPrevention
    {
        keepInHistory,
        prevent,
        keepButDisable, // Keeps the entry in the history, but makes it disabled.
    }
    

    এখন কি হবে? doSomethingপ্রত্যাশার মতো পদ্ধতি কি কাজ করবে? এটি প্রতিরোধের জন্য, শুরু থেকে এই পদ্ধতিটি এইভাবে লিখতে হবে:

    void doSomething(undoPrevention preventUndo)
    {
        if (![undoPrevention.keepInHistory, undoPrevention.prevent].contains(preventUndo))
        {
            throw new ArgumentException('preventUndo');
        }
    
        doTheJob();
        if (preventUndo == undoPrevention.prevent)
        {
            this.undoHistory.discardLastEntry();
        }
    }
    

    বুলিয়ানগুলি ব্যবহার করে এমন রূপটি দেখতে খুব সুন্দর দেখাচ্ছে!

    void doSomething(bool preventUndo)
    {
        doTheJob();
        if (preventUndo)
        {
            this.undoHistory.discardLastEntry();
        }
    }
    

3
"এটি অত্যধিক কোড ( এছাড়াও, আপনি যদি বুলিয়ান ব্যবহার করেন তবে যাইহোক আপনার একটি বিবৃতি প্রয়োজন। সত্যি কথা, আপনার এই সমালোচনাটি আমার কাছে কিছুটা কৃত্রিম বলে মনে হচ্ছে।
জর্জিও

1
আমি এখানে একটি বিকল্প সমাধান অনুপস্থিত। আপনি কি বলছেন যে তাঁর সত্য-মিথ্যা কিছু বলা উচিত নয় এবং আইডিই (যা তিনি ব্যবহার করেন না) এর উপর নির্ভর করুন? একটি মন্তব্য ভেরিয়েবল নামের মতো পচে যেতে পারে।
নিরাপদ

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

4
@ সুপারএম কোডটির সাথে সিঙ্কে মন্তব্যগুলি রাখা সত্যিই খুব ঝামেলার ঝুঁকিপূর্ণ, যেহেতু আপনার অসামঞ্জস্যতার জন্য অনুসন্ধানে আপনার সংকলক থেকে আপনার কোনও সহায়তা নেই।
বুহব

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

20

উভয়ই নয়, আপনার বুলিয়ান পতাকা সহ পদ্ধতিগুলি লিখতে হবে না।

রবার্ট সি মার্টিনের উদ্ধৃতি দিতে তার বই ক্লিন কোড (আইএসবিএন -13 978-0-13-235088-4) এ বলেছেন, "একটি অনুষ্ঠানে একটি বুলিয়ান পাস করা সত্যিই ভয়ঙ্কর অনুশীলন" "

তাকে চিত্রিত করার জন্য, যুক্তিটি হ'ল আপনার সত্য / মিথ্যা স্যুইচ হওয়ার অর্থ হল যে আপনার পদ্ধতিটি সম্ভবত দুটি পৃথক কাজ করে (যেমন "পূর্বাবস্থায় কিছু করুন" এবং "পূর্বাবস্থায় কিছু না করে"), এবং তাই হওয়া উচিত দুটি পৃথক পদ্ধতিতে বিভক্ত (এটি অভ্যন্তরীণভাবে একই জিনিসটিকে কল করতে পারে)।

DoSomething()
{...

DoSomethingUndoable()
{....

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

4
সমস্ত উত্তর পড়ার পরে এবং আমার কোডটি দেখার পরে আমি এই সিদ্ধান্তে পৌঁছে যাচ্ছি যে এটি করার সঠিক উপায় is doSomethingUndoable()পরিবর্তনগুলি ক্যাপচার করতে পারে এবং তারপরে কল করতে পারেdoSomething()
মেথডেফ্যাকশন

1
সুতরাং আমার যদি এমন একটি ফাংশন থাকে যা প্রচুর প্রসেসিং করে এবং এটি সম্পন্ন করার সময় ইমেল প্রেরণের বিকল্প থাকে তবে আমার কাছে এমন কোনও বুলিয়ান যুক্তি থাকা উচিত নয় যা ইমেলটি প্রেরণে বাধা দিতে পারে, আমার একটি আলাদা ফাংশন তৈরি করা উচিত?
ইয়াকাত্জ

2
@ কালেব এই ক্ষেত্রে আমি একটি হটডগ তৈরি করব এবং উপাদানগুলি একে অপরের সাথে যুক্ত করব , বা দৃ a়ভাবে টাইপ করা ভাষায় আমি একটি বস্তু হটডগসেটেটিংগুলি পাস করবো যাতে আমি সমস্ত বুলিয়ান পতাকা স্থাপন করতাম। আমার কাছে 15 টি ভিন্ন ভিন্ন সত্য / মিথ্যা পতাকা নেই যা বজায় রাখার জন্য দুঃস্বপ্ন হবে। মনে রাখবেন যে কোডটি রক্ষণাবেক্ষণ সম্পর্কে নয় যেহেতু অ্যাপ্লিকেশন ব্যয়ের 80% ছিল। var hd = MakeHotDog (); hd.Add (পেঁয়াজ); ...
নিক বি।

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

5

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

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


4

যুক্তির ভূমিকা সংজ্ঞায়িত করা কলারের ভূমিকা নয়। আমি সর্বদা ইনলাইন সংস্করণে যাই এবং যদি আমার সন্দেহ থাকে তবে ডাকা ফাংশনের স্বাক্ষরটি যাচাই করে নিই।

চলতি ক্ষেত্রের ভূমিকা অনুসারে পরিবর্তনশীল নামকরণ করা উচিত। তাদের পাঠানোর সুযোগটি নয়।


1
বর্তমান স্কোপে ভেরিয়েবলের ভূমিকা হ'ল এটি কী জন্য ব্যবহৃত হয় তা বলা। আমি দেখতে পাচ্ছি না যে এটি কীভাবে অস্থায়ী ভেরিয়েবলগুলির ওপির ব্যবহারের সাথে বিরোধিতা করে।
সুপারম

4

আমি জাভাস্ক্রিপ্টে যা করব তা হ'ল ফাংশনটি কোনও অবজেক্টটিকে এই জাতীয় কিছু হিসাবে দেখাবে:

function doSomething(settings) {
    var preventUndo = settings.hasOwnProperty('preventUndo') ? settings.preventUndo : false;
    // Deal with preventUndo in the normal way.
}

তারপরে এটিকে কল করুন:

doSomething({preventUndo: true});

স্বাস্থ্য সহকারীর !!! আমরা দুজনেই একটা doSomething(x)পদ্ধতি বানিয়েছি ! হ্যাঁ ... আমি আপনার পোস্টটি এখনও অবধি লক্ষ্য করিনি।
ব্লেশ

যদি আমি "নুন্ডো" স্ট্রিংটি পাস করি তবে কী ঘটবে, এবং আপনার স্বাক্ষর ব্যবহারকারী ব্যক্তির পক্ষে কীভাবে সেটি পরিষ্কার হয়ে যায় যে বাস্তবায়নের দিকে নজর না দিয়ে কী সেটিংস ধারণ করে?
নিক বি।

1
আপনার কোড নথি। অন্য সবাই এটাই করে। এটি আপনার কোড পড়া সহজ করে তোলে, এটি লেখার জন্য কেবল একবারই ঘটতে হবে।
উপহাস 2

1
@NickB। সম্মেলন শক্তিশালী। যদি আপনার বেশিরভাগ কোড যুক্তিযুক্ত জিনিসগুলি গ্রহণ করে তবে এটি পরিষ্কার।
অরিপ

4

আমি নিজেকে স্পষ্ট করতে সহায়তা করার জন্য ভাষা বৈশিষ্ট্যগুলি লাভবান করার শখ করছি। উদাহরণস্বরূপ সি # তে আপনি নাম দ্বারা প্যারামিটার নির্দিষ্ট করতে পারেন:

 CallSomething(name: "So and so", age: 12, description: "A random person.");

জাভাস্ক্রিপ্টে, আমি সাধারণত এই কারণে একটি যুক্তি হিসাবে একটি বিকল্প বস্তু ব্যবহার করতে পছন্দ করি:

function doSomething(args) { /*...*/ }

doSomething({ name: 'So and so', age: 12, description: 'A random person.' });

যদিও এটি কেবল আমার পছন্দ। আমি মনে করি এটি যে পদ্ধতিটি ডাকা হচ্ছে তার উপর এবং আইডিই কীভাবে বিকাশকারীকে স্বাক্ষর বুঝতে সহায়তা করে তার উপর নির্ভর করে।


1
আলগাভাবে টাইপ করা ভাষাগুলির এটাই "ডাউনসাইড"। আপনি কিছু বৈধতা ছাড়া সত্যই একটি স্বাক্ষর প্রয়োগ করতে পারবেন না। আমি জানতাম না যে আপনি জেএস-তে এর মতো নাম যুক্ত করতে পারেন।
জেমস পি।

1
@ জেমসপলসন: আপনি সম্ভবত জানতেন যে আপনি জেএসে এটি করতে পেরেছিলেন এবং এটি উপলব্ধি করেন নি। এটি $.ajax({url:'', data:''})
জিকুয়ারি

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

3

আমি এটি পড়তে সবচেয়ে সহজ এবং সহজ:

enum Undo { ALLOW, PREVENT }

doSomething(Undo u) {
    if (Undo.ALLOW == u) {
        // save stuff to undo later.
    }
    // do your thing
}

doSomething(Undo.ALLOW);

মাইনমা ​​পছন্দ করে না। আমাদের দ্বিমত পোষণ করতে রাজি হতে পারে, বা আমরা জোশুয়া ব্লচ প্রস্তাবিত একটি সমাধান ব্যবহার করতে পারি:

enum Undo {
    ALLOW {
        @Override
        public void createUndoBuffer() {
            // put undo code here
        }
    },
    PREVENT {
        @Override
        public void createUndoBuffer() {
            // do nothing
        }
    };

    public abstract void createUndoBuffer();
}

doSomething(Undo u) {
    u.createUndoBuffer();
    // do your thing
}

এখন আপনি যদি কখনও একটি পূর্বাবস্থায় যোগ করেন L LIMITED_UNDO, আপনি কোডUndoBuffer () পদ্ধতিটি প্রয়োগ না করে আপনার কোডটি সংকলন করবে না। এবং ডসোমথিং-এ () পূর্বে (Undo.ALLOW == u) নেই no আমি এটি উভয় উপায়েই করেছি এবং দ্বিতীয় পদ্ধতিটি ভারী ওজন এবং যখন পূর্বাবস্থায় এনামগুলি পৃষ্ঠা এবং কোডের পৃষ্ঠাগুলিতে প্রসারিত হয় তখন কিছুটা বোঝা শক্ত হয় তবে এটি আপনাকে ভাবিয়ে তোলে। আমি পরিবর্তনের কারণ না পাওয়া পর্যন্ত আমি সাধারণত সাধারণ বুলিয়ানকে 2-মান এনাম দিয়ে প্রতিস্থাপন করতে সহজ পদ্ধতির সাথে থাকি। আমি যখন তৃতীয় মান যুক্ত করি, তখন আমি আমার আইডিইটি "সন্ধান-ব্যবহারগুলি" ব্যবহার করতে এবং তারপরে সমস্ত কিছু ঠিক করে ফেলি।


2

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

আমি দুটি বিকল্পের কথা ভাবতে পারি যা একটি অতিরিক্ত পরিবর্তনশীল জড়িত না:

1. একটি অতিরিক্ত মন্তব্য ব্যবহার করুন

doSomething(/* preventUndo */ true);

২. বুলিয়ানের পরিবর্তে দ্বি-মূল্যবান এনাম ব্যবহার করুন

enum Options
{
    PreventUndo,
    ...
}

...

doSomething(PreventUndo);

আপনার ভাষা যদি এনামগুলিকে সমর্থন করে তবে আপনি বিকল্প 2 ব্যবহার করতে পারেন।

সম্পাদনা

অবশ্যই, নামযুক্ত তর্কগুলি ব্যবহার করাও একটি বিকল্প, যদি আপনার ভাষা তাদের সমর্থন করে।

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

if (preventUndo)
{
    ...
}

তোমার আছে

if (undoOption == PreventUndo)
{
    ...
}

অথবা

switch (undoOption)
{
  case PreventUndo:
  ...
}

এবং এটি যদি আরও বেশি টাইপ করা হয় তবে মনে রাখবেন যে কোডটি একবার লেখা হয়েছিল এবং বহুবার পড়েছে, সুতরাং ছয় মাস পরে আরও পঠনযোগ্য কোড সন্ধানের জন্য এটি এখন আরও কিছুটা টাইপ করা সার্থক হতে পারে।


2

@ গ্লেনপিটারসন যা বলেছেন তার সাথে আমি একমত:

doSomething(Undo.ALLOW); // call using a self evident enum

তবে আমার কাছে মনে হয় কেবল দুটি সম্ভাবনা রয়েছে (সত্য বা মিথ্যা)

//Two methods    

doSomething()  // this method does something but doesn't prevent undo

doSomethingPreventUndo() // this method does something and prevents undo

2
সুন্দর ধারণা - আমি এটি ভাবিনি। আপনি যখন ডসোমিংথিংয়ের মতো আরও জটিল হন (স্ট্রিং, স্ট্রিং, স্ট্রিং, বুলিয়ান, বুলিয়ান, বুলিয়ান) তখন নামযুক্ত ধ্রুবকগুলি কেবল যুক্তিসঙ্গত সমাধান। হ্যাঁ, জোশ ব্লচ একটি কারখানা এবং নির্মাণকারী অবজেক্টটিকে নীচের মতো পরামর্শ দিয়েছেন: মাইথিংমেকার টেকমেকার = মাইথিংমেকার.নেউ (); thingMaker.setFirstString ( "হাই"); thingMaker.setSecondString ( "আছে"); ইত্যাদি ... জিনিস টি = জিনিসমেকার.মেকআইটি (); t.doSomething (); এটি কেবল আরও অনেক কাজ, সুতরাং এটির পক্ষে এটি আরও ভাল হওয়া উচিত।
গ্লেনপিটারসন

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

@ গ্লেনপিটারসন একটি ফ্যাক্টরি একটি সম্ভাবনা এবং এটি জাভাস্ক্রিপ্টে সম্ভব (ওপি দ্বারা উল্লেখ করা)।
জেমস পি।

2

যেহেতু আপনি জাভাস্ক্রিপ্ট সম্পর্কে মূলত জিজ্ঞাসা করছেন, কফিস্ক্রিপ্ট ব্যবহার করে আপনার সিনট্যাক্সের মতো একটি নামযুক্ত যুক্তি থাকতে পারে, খুব সহজ:

# declare method, ={} declares a default value to prevent null reference errors
doSomething = ({preventUndo} = {}) ->
  if preventUndo
    undo = no
  else
    undo = yes

#call method
doSomething preventUndo: yes
#or 
doSomething(preventUndo: yes)

সংকলন

var doSomething;

doSomething = function(_arg) {
  var preventUndo, undo;
  preventUndo = (_arg != null ? _arg : {}).preventUndo;
  if (preventUndo) {
    return undo = false;
  } else {
    return undo = true;
  }
};

doSomething({
  preventUndo: true
});

doSomething({
  preventUndo: true
});

সম্ভাবনার চেষ্টা করতে http://js2coffee.org/ এ কিছু মজা করুন


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

1

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

var doSomethingOptions = new Array();

doSomethingOptions["PREVENTUNDO"] = true;
doSomethingOptions["TESTMODE"] = false;

doSomething( doSomethingOptions );

// ...

function doSomething( doSomethingOptions ){
    // Check for null here
    if( doSomethingOptions["PREVENTUNDO"] ) // ...
}

আমি বুঝতে পারি এটি দৃ someone়ভাবে টাইপযুক্ত ব্যাকগ্রাউন্ডের কারওর প্রতিচ্ছবি এবং এটি সম্ভবত ব্যবহারিক না হলেও এটি মৌলিকতার জন্য বিবেচনা করুন।

আরেকটি সম্ভাবনা হ'ল কোনও জিনিস থাকা এবং জাভাস্ক্রিপ্টে এটিও সম্ভব। আমি এটি 100% নিশ্চিত নই যে এটি সিনট্যাক্সিকভাবে সঠিক। আরও অনুপ্রেরণার জন্য ফ্যাক্টরির মতো নিদর্শনগুলি দেখুন।

function SomethingDoer( preventUndo ) {
    this.preventUndo = preventUndo;
    this.doSomething = function() {
            if( this.preventUndo ){
                    // ...
            }
    };
}

mySomethingDoer = new SomethingDoer(true).doSomething();

1
আমি মনে করি doSomethingOptions.PREVENTUNDOঅ্যারে অ্যাক্সেস নোটেশনের পরিবর্তে ডট-নোটেশন ( ) এ আরও ভাল লেখা যেতে পারে ।
পাওলো ইবারম্যান

1

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

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

উদাহরণ:

// C# 4
foo.doSomething(preventUndo: true);
# Python
foo.doSomething(preventUndo=True)
// Objective-C
[foo doSomethingWith:bar shouldPreventUndo:YES];

0

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

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


সুতরাং আপনি দুটি ফাংশনে বুলিয়ান আর্গুমেন্টের সাথে একটি ফাংশন রূপান্তর করবেন যা কেবল তাদের কোডের একটি ক্ষুদ্র অংশে পৃথক (যেখানে মূলটির সাথে একটি থাকবে if(param) {...} else {...})?
পাওলো ইবারম্যান

-1
int preventUndo = true;
doSomething(preventUndo);

নিম্নতর লেভেল ভাষার জন্য যেমন সি ++ এর জন্য একটি ভাল সংকলক নীচের হিসাবে 2 লাইনের উপরে মেশিন কোডটি অনুকূলিত করবে:

doSomething(true); 

সুতরাং এটি পারফরম্যান্সে গুরুত্বপূর্ণ নয় তবে পাঠযোগ্যতা বৃদ্ধি করবে।

এটি পরে পরিবর্তনশীল হয়ে ওঠে এবং অন্যান্য মানগুলিও গ্রহণ করতে পারে এমন ক্ষেত্রে এটি একটি ভেরিয়েবল ব্যবহার করা সহায়ক।

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