একক অ্যারে বনাম ফাংশনে একাধিক যুক্তি


24

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

function searchQuery($params = array()) {
    foreach($params as $param => $value) {
        switch ($param) {
            case 'name':
                $query->where('name', $value);
                break;
            case 'phone':
                $query->join('phone');
                $query->where('phone', $value);
                break;
        }
    }
}

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

function searchQuery($name = '', $phone = '') {
    if ($name) {
        $query->where('name', $value);
    }

    if ($phone) {
        $query->join('phone');
        $query->where('phone', $value);
    }
}

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

আমার সমস্যাটি হ'ল 10+ এর মতো প্রচুর আর্গুমেন্টের সাথে ডিল করার সময় এটি খুব ভার্জোজ হয়। কোন পছন্দসই অনুশীলন আছে? আমার নিকৃষ্টতম পরিস্থিতিটি নীচের মতো কিছু দেখতে পাবে:

searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')


1
যদি ফাংশনটি নির্দিষ্ট কীগুলি প্যারামিটার হিসাবে প্রত্যাশা করে, তবে কমপক্ষে সেই কীগুলি ডকব্লক-তে নথিভুক্ত করা উচিত - এইভাবে আইডিইগুলি কোডটি আবিষ্কার না করে প্রাসঙ্গিক তথ্য প্রদর্শন করতে পারে। en.wikipedia.org/wiki/PHPDoc
Ilari Kajaste

2
পারফরম্যান্স টিপ: foreachএই উদাহরণে অপ্রয়োজনীয়, আপনি এর if(!empty($params['name']))পরিবর্তে foreachএবং ব্যবহার করতে পারেন switch
chiborg

1
আপনার এখন একটি পদ্ধতি রয়েছে যা আপনি ব্যবহার করেন। আমি এখানে একবার দেখার পরামর্শ দিই: আরও পদ্ধতি তৈরি করার জন্য book.cakephp.org/2.0/en/models/… । এগুলি এমনকি স্ট্যান্ডার্ড সন্ধানের জন্য যাদুকরীভাবে উত্পন্ন হতে পারে এবং নির্দিষ্ট অনুসন্ধানগুলির জন্য কাস্টম হিসাবে বিকাশ করা যেতে পারে। সাধারণভাবে এটি মডেলের ব্যবহারকারীদের জন্য একটি স্পষ্ট এপিআই তৈরি করে।
লুক ফ্রাঙ্কেন


2
উপরের 'পারফরম্যান্স টিপ'-এর একটি নোট: !empty($params['name'])প্যারামিটারগুলির জন্য পরীক্ষা করার জন্য অন্ধভাবে ব্যবহার করবেন না - উদাহরণস্বরূপ, স্ট্রিং "0" খালি থাকবে। array_key_existsচাবিটি পরীক্ষা করার জন্য, বা issetযদি আপনার যত্ন নেই তবে এটি ব্যবহার করা ভাল null
AmadeusDrZaius

উত্তর:


27

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

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


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

2
@ জিয়ানকাই সেই উদাহরণে আমি সম্ভবত whereযুক্তিগুলির জন্য একটি অ্যারে পরম তৈরি করব , একটি joinনির্দিষ্টকরণকারীর জন্য ইত্যাদি them তাদের যথাযথভাবে নামকরণ করে এটি এখনও স্ব-ডকুমেন্টিং হবে।
জান ডোগজেন

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

আমি চ্যালেঞ্জ জানাব যে ওপির পছন্দটি "কম পাঠযোগ্য" (কিভাবে?) এবং কম রক্ষণাবেক্ষণযোগ্য। অনুসন্ধানের অনুসন্ধানগুলি ('', '', '', '', 'ফু', '', '', '', 'বার') অনুসন্ধানের তুলনায় খুব কম পঠনযোগ্য বা রক্ষণাবেক্ষণযোগ্য নয় (['q' => 'ফু', 'x' => 'বার']) প্রচুর যুক্তি অগত্যা হয় কোনও কোড-গন্ধ; উদাহরণস্বরূপ একটি জিজ্ঞাসা ()। এমনকি অল্প সংখ্যক তর্ক যুক্তির জন্যও, যুক্তি ক্রমে সামঞ্জস্যতার অভাব ঘটে যখন যুক্তিগুলি পাস করা হয় তখন সরাসরি বোঝায় যে এটি হার্ডকোড পরামিতিগুলির জন্য কী খারাপ ধারণা। অসম্পূর্ণতার জন্য পিএইচপি-তে কেবল স্ট্রিং এবং অ্যারে ফাংশনগুলি দেখুন।
মাইকচিনকেলে

4

আমার উত্তর কম-বেশি ভাষা অজ্ঞাব্য।

কোনও জটিল ডেটা স্ট্রাকচার (টেবিল, রেকর্ড, ডিকশনারি, অবজেক্ট ...) এ আর্গুমেন্টগুলির গ্রুপ করার একমাত্র উদ্দেশ্য যদি এগুলি পুরোপুরি কোনও ফাংশনে পৌঁছে দেয় তবে আরও ভাল এড়াতে পারেন। এটি জটিলতার একটি অকেজো স্তর যুক্ত করে এবং আপনার উদ্দেশ্যকে অস্পষ্ট করে তোলে।

যদি গোষ্ঠীযুক্ত যুক্তিগুলির নিজের দ্বারা কোনও অর্থ থাকে, তবে জটিলতার সেই স্তরটি পুরো নকশাটি বুঝতে সহায়তা করে: পরিবর্তে এটি বিমূর্তির স্তরটির নাম দিন।

আপনি দেখতে পাচ্ছেন যে এক ডজন পৃথক যুক্তি বা একটি বড় অ্যারের পরিবর্তে, সেরা ডিজাইনটি প্রতিটি গ্রুপের পারস্পরিক সম্পর্কযুক্ত ডেটা দুটি বা তিনটি যুক্তি দিয়ে।


1

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

আপনার searchQueryফাংশনটির মাধ্যমে কোন পরামিতিগুলি প্রত্যাশিত তা দেখতে আমাকে আপনার ফাংশনটি বাস্তবায়নের মধ্য দিয়ে যেতে হবে ।

আমি কেবলমাত্র আপনার ক্ষেত্রে প্রথমে অগ্রাধিকার চাই যখন searchQueryকেবলমাত্র একটি টেবিলের মধ্যে সন্ধানের মধ্যে সীমাবদ্ধ থাকে, যাতে কোনও যোগ দেওয়া হবে না। সেক্ষেত্রে আমার ফাংশনটি দেখতে এমন হবে:

function searchQuery($params = array()) {
    foreach($params as $param => $value) {
        $query->where($param, $value);
    }
} 

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


1

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

আমি প্রশ্ন মন্তব্যগুলি থেকে @ চিবার্গের পরামর্শটি ব্যবহার করার জন্য দৃ suggest়ভাবে পরামর্শ দিচ্ছি - আপনি কী চান তা এটি আরও পরিষ্কার।

function searchQuery($params = array()) {
    $defaults = array(
        'name' => '',
        'phone' => '',
        ....
    );
    $params = array_merge($defaults, $params);

    if(!empty($params['name'])) {
        $query->where('name', $params['name']);
    }
    if (!empty($params['phone'])) {
        $query->join('phone');
        $query->where('phone', $params['phone']);
    }
    ....
}

0

এছাড়াও আপনি ক্যোয়ারী স্ট্রিংয়ের অনুরূপ একটি স্ট্রিং পাস করতে পারেন এবং ব্যবহার করতে পারেন parse_str(কারণ আপনি পিএইচপি ব্যবহার করছেন বলে মনে হয় তবে অন্যান্য সমাধান সম্ভবত অন্যান্য ভাষায় পাওয়া যায়) এটি পদ্ধতির অভ্যন্তরে অ্যারেতে প্রসেস করতে:

/**
 * Executes a search in the DB with the constraints specified in the $queryString
 * @var $queryString string The search parameters in a query string format (ie
 *      "foo=abc&bar=hello"
 * @return ResultSet the result set of performing the query
 */
function searchQuery($queryString) {
  $params = parse_str($queryString);
  if (isset($params['name'])) {
    $query->where('name', $params['name']);
  }
  if (isset($params['phone'])) {
    $query->join('phone');
    $query->where('phone', $params['phone']);
  }
  ...

  return ...;
}

এবং এটি পছন্দ করুন

$result = searchQuery('name=foo&phone=555-123-456');

আপনি http_build_queryকোনও এসোসিয়েটিভ অ্যারে থেকে স্ট্রিংয়ে রূপান্তর করতে ব্যবহার করতে পারেন (বিপরীত যা parse_strহয়)।

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