[英]How to refactor huge lookup table in Ruby
我有一個方法:
def assign_value
...
@obj.value = find_value
end
和一個巨大的查詢表:
def find_value
if @var > 0 && @var <= 30
0.4
elsif @var > 30 && @var <= 50
0.7
elsif @var > 50 && @var <= 70
1.1
elsif @var > 70 && @var <= 100
1.5
elsif @var > 100 && @var <= 140
2.10
elsif @var > 140 && @var <= 200
2.95
elsif @var > 200 && @var <= 300
4.35
elsif @var > 300 && @var <= 400
6.15
elsif @var > 400 && @var <= 500
7.85
elsif @var > 500 && @var <= 600
9.65
...
end
以此類推1800行
不用說,它是給一個未命名國家的稅務部門的。 現在,它是手動編寫的(全部1800行)以說明整數范圍和十進制返回值的變化長度。
如果不重寫整個國家的稅法,我將如何重構呢?
范圍和值確實會每年更改,因此我們需要保持向后兼容性。 數據庫表將簡化事務,但是由於我們要處理的是多個不同的國家,每個國家都有不同的要求和稅法,因此創建數據庫表並不像聽起來那樣簡單。
@MilesStanfield的回答與您的影響幾乎相同。 如我的評論所述,我將使用散列來擺脫所有條件(或情況):
COUNTRY_TAX_RATES = {
0..30 => 0.4,
31..50 => 0.7,
51..70 => 1.1
}
COUNTRY_TAX_RATES[0..30] # 0.4
COUNTRY_TAX_RATES.select { |code| code === 10 }.values.first # 0.4
如果您不更改代碼,通常可以使用它。 如果確實經常更改,則可以考慮使用另一種方法(例如,存儲在db中並通過用戶界面進行管理)。
更新:現在我不再在手機上了,我想進一步擴大這個答案。 似乎您無視@Wand Maker的建議,但我認為您不應該這樣做。
假設您使用我的哈希。 它很方便,沒有任何條件,並且易於調整。 但是,正如Wand Maker指出的那樣,每次更改范圍或十進制時,您都需要開發人員來更新代碼。 這可能沒問題,因為您只需要每年進行一次,但這不是最干凈的方法。
您希望會計師能夠代替開發人員來更新稅率和代碼。 因此,您可能應該創建一個包含這些屬性的表。 我不確定您的示例中的范圍和小數表示什么,但我希望您能理解:
Tax (ActiveRecord) with range_column (Give this an explicit, explanatory name. You could also use min and max range columns), code, rate and country_id
class Tax < ActiveRecord::Base
serialize :range_column
belongs_to :country
end
Country has_many :taxes
如果您想知道馬耳他的稅率(country_id:30),稅碼為40(這可能意味着什么),您可以執行以下操作:
Tax.select(:tax_rate).joins(:country).find_by(country_id: 30, range_column: 40).tax_rate # you might need a between statement instead, can't check right now if querying a serialized hash works like this
現在,當這些更改更改時,會計師可以更新范圍,小數或任何其他屬性(當然,您必須首先為其創建CRUD)。
附:不要介意命名,不確定這些數字代表什么。 :)
我將使用帶有范圍的case語句
case @var
when 0..30 then 0.4
when 31..50 then 0.7
when 51..70 then 1.1
...
end
假設inc
是收入,而arr
是成對的數組[bp, tax]
,其中
arr[0][0] = 0
,意味着arr
的第一個元素的bp
(收入“斷點”)為零; arr[i][0] < arr[i+1][0]
,這意味着斷點在增加; inc >= arr[-1][0]
,則應納稅arr[-1][1]
inc >= arr[-1][0]
; 和 arr[i][0] <= inc < arr[i+1][0]
, 0 <= i <= arr.size-2
納稅arr[i][1]
。 然后可以計算稅收
arr.find { |bp,_| inc >= bp }.last
因為斷點在增加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.