2017-10-18 25 views
1

如果標題不清楚,我很抱歉,但我覺得這很難描述。基本上,我有一個函數可以查找類(學校類)的實例,並給出班級ID號和日期。如果需要,該函數還可以創建一個新的類實例。如何將布爾參數傳遞給函數以充當開關?

function get_class_instance($class_id, $date, $create) 

該函數內部使用類標識碼和日期作爲參數的class_instances數據庫中選擇表。如果找到匹配的class_instance,則返回其ID。如果沒有找到,則有一個條件可以使創建參數。如果是,則使用數據庫插入創建新的class_instance,並返回其ID。如果爲false,則數據庫中沒有任何更改,並返回false

我還是一個初學PHP和一般編碼,所以我想這可能是一個更好的方法。問題是,在調用函數時,可能不清楚爲什麼有一個布爾值被傳遞。

$original_cinstance_id = get_class_instance($original_class_id, $original_date, 1); 
+0

查找 「統計員」。我不認爲它真的有那麼多問題,但根據被傳遞的標誌的性質,你可以創建一個基本上賦予布爾或整數標誌語法含義的幫助數據結構。 – slackOverflow

+0

你在找什麼像[this](https://stackoverflow.com/questions/34298241/passing-a-strings-true-false-boolean-value-into-a-functions-argument) –

+0

可能的重複[將字符串的真/假布爾值傳遞給函數參數](https://stackoverflow.com/questions/34298241/passing-a-strings-true-false-boolean-value-into-a-functions-argument) –

回答

2

將函數布爾標誌傳遞給兩個不同的事物而不是一個,被認爲是的的Clean Code book。建議更好的選擇將是有兩個功能get_whatevercreate_whatever

雖然Code Smell取決於上下文,但我認爲布爾標誌的氣味適用於這種情況,因爲創建一些東西與僅僅讀取它不同。前者是命令,後者是查詢。 So they should be separated。一個改變狀態,另一個不改變狀態。它使更好的語義和separation of concerns拆分它們。此外,它將減少函數的Cyclomatic Complexity一個分支,所以您將需要一個單元測試來減少它。

報價https://martinfowler.com/bliki/FlagArgument.html

布爾參數大聲宣佈這個功能確實不止一兩件事。他們混亂,應該被淘汰。

這裏引用http://www.informit.com/articles/article.aspx?p=1392524

我的理由是,不同的方法傳達更清楚我的意圖是什麼,當我撥打電話。當我看到book(martin, false)時,我不需要記住標誌變量的含義,我可以輕鬆閱讀regularBook(martin)

附加討論和閱讀材料:

+0

謝謝。所以我假設'create_whatever'的邏輯將始終存在於與get_whatever相同的級別的代碼中?換句話說,我應該在控制器中保留這個邏輯而不是模型? – cbunn

+0

@cbunn控制器的責任是接受請求並委託給模型。該模型包含創建或獲取任何內容的實際邏輯。所以你會在兩個層都有兩種方法。 – Gordon

+0

如果我理解「代碼異味」的概念,那麼重點就是描述那些實際上並不是很糟糕的事情,或者甚至導致不好的事情,但是它們代表了底層代碼中更糟的問題。如果你要聲明一些代碼味道,那麼你必須說明它是什麼意思,否則你基本上只是說「我不喜歡它」。 (這就是爲什麼我對「代碼味道」不感興趣的原因,它很容易成爲一種將個人風格考慮提升爲好與壞的方法) – slackOverflow

1

而是傳遞一個數值,你可以通過這樣一個真正的布爾值:

$original_cinstance_id = get_class_instance($original_class_id, $original_date, true); 

另外在你的函數的聲明,你可以指定一個默認值,以避免傳遞布爾每次:

function get_class_instance($class_id, $date, $create = false) 
+0

謝謝。數值和布爾值之間的差異並不令我擔心。無論是哪種情況,更難以知道該國旗的目的是什麼。所以,我會爲未來保留默認值,但我認爲@戈登是正確的,這是不好的形式。 – cbunn

2

您可以使用創建一個默認值,所以如果你通過什麼,它充當數據庫的一個正常的「獲取」操作。就像這樣:

function get_class_instance($class_id, $date, $create = false); 

您可以查詢您的ID是這樣的:

$class_id = get_class_instance(1, "18-10-2017"); 

然後,您可以通過「真」到它時,你需要在數據庫中創建它:

$class_id = get_class_instance(1, "18-10-2017", true); 
+0

謝謝。我其實只是讀了關於默認值,但並沒有想到在這裏應用。我會爲未來記住它,但我認爲@戈登是正確的,這是糟糕的形式。 – cbunn

+0

當您擁有一個具有自動完成功能的合理IDE時,使用可選參數沒有任何問題。如果這是一種糟糕的形式,那麼每種語言都不會實現此功能。閱讀更多:https://softwareengineering.stackexchange.com/questions/22559/are-optional-parameters-helpful-or-a-hindrance-to-application-maintenance –

+0

這不是關於擁有一個* optional *參數,而是明確地具有導致函數具有*多行爲*的布爾標誌。閱讀更多信息:https://softwareengineering.stackexchange。com/questions/147977/is-it-it-wrong-to-use-a-boolean-parameter-to-determine-behavior – Gordon

1

一種選擇是創建一個枚舉器,如下所示:

abstract class create_options { 
    const no_action = 0; 
    const create = 1; 
} 

所以現在你的函數調用是這樣的:

$original_cinstance_id = get_class_instance($original_class_id, $original_date, create_options::no_action); 
在實踐

只要你的代碼有很好的註釋,那麼這是不是布爾標誌一個主要問題,但如果你有一打有可能的選擇不同的結果,那麼這可能是有用的。

正如其他人所提到的,在很多語言中,您還可以使參數成爲可選參數,並具有默認行爲,除非調用方明確定義了該參數。

+0

我認爲這種方法是矯枉過正的。 @TahaPasku方法看起來更好 – Akintunde007

+0

我同意這種情況的矯枉過正,我在最後說了很多。如果情況變得更復雜,它仍然很高興知道這個選項。 – slackOverflow

+0

我認爲這是最好的解決方案 - 儘管你今天可能會傳遞一個布爾值,誰知道你明天可能會通過什麼。您可能需要更加豐富的背景,該解決方案提供了可擴展性。另外,如果您需要知道代碼中使用了「創建」選項的位置,則可以使用IDE工具查找類常量的用法。另一種方法是使用動態類型的'0/false/null/[]/array()/ etc.'值,難以準確而全面地在代碼庫中追蹤。 –