大話重構 之 你的參數列表像蚯蚓一樣讓人厭惡嗎


checkout("zhangsan", "chengdu",
			"236891001Y", 1, 1.59,
			"279645311R", 2, 2.50,
			"357498670R", 1, 19.90,
			"139776685")

不知道小伙伴們看到上面的函數有何感想?一碼是真的有股罵人的沖動。這一二一,一二一的,是在走正步嗎?天知道是什么意思。如果你在一個大型商業項目中編寫代碼,則一定碰到過比這還凌亂的參數列表。。。想罵就罵吧,別憋出內傷。&#*``...

長參數列表的由來

為啥會寫出這么長的參數列表呢?

還真是有說法的。在面向過程的語言中,全局變量會使人陷入問題和調試的深淵。為了避免使用全局變量,大伙都謹遵一條法則:需要啥就向函數傳啥。

到了面向對象語言中,有人依然沒有適應過來,在沒人提醒的情況下,然后。。。就沒有然后了。

一碼今天就來提醒依然有這個問題的小伙伴們。

合理構建對象,隱藏部分數據

在面向對象的語言中,對象即為數據和行為的結合體。對象有了數據,再調用對象方法的時候,需要傳的數據就少多了。

前提是構建合理的對象,讓它封裝一部分數據。

拿篇首的例子來說,checkOut是選好商品后,去買單的意思。買單得有個人吧,消費者出來了。

case class Customer(name: String, address: String)

val customer = Customer("zhangsan", "chengdu")
customer.checkout("236891001Y", 1, 1.59,
			"279645311R", 2, 2.50,
			"357498670R", 1, 19.90,
			"139776685")

消費者一出,參數減少了兩個。

該重構手法叫 提取類 ,在 消除過長類 中也有使用。

引入參數對象

繼續識別對象。購物嘛,薯片1盒,蘋果兩斤,打包成對象,多個同類產品構成訂單項,多個訂單項構成訂單。

case class Product(id: String, price: Float)
case class OrderItem(amount: Int, product: Product)
case class Order(id: String, items: List[OrderItem])

val orderItems = List(
	OrderItem(1, Product("236891001Y", 1.59)),
	OrderItem(2, Product("279645311R", 2.50)),
	OrderItem(1, Product("357498670R", 19.90))
)
val order = Order("139776685", orderItems)

customer.checkout(order)

主謂賓,和造句一樣,整個代碼終於又有畫面感了。道法自然,面向對象的代碼也講究自然。一個商業項目的代碼會維護較長時間,人要讀很多次,所以寫代碼一定要講人話。面向對象對可讀性的貢獻不可謂不大。

這種重構的手法,叫 引入對象參數 。顧名思義,把參數列表中相關度較高的參數打包形成對象,進而減少參數數量。該重構手法在 消除過長方法 一文中也有使用。

除了上面的重構手法,還可以通過下面兩種手法減少參數數量。

保持對象完整

如果發現方法的參數里面有多個來自於一個對象,那么就直接傳入這個對象。

val begin = dateRange.begin
val end = dateRange.end

withinPlan = plan.withinRange(begin, end)

重載個withinRange方法,支持直接傳入完整的DateRange對象。

withinPlan = plan.withinRange(dateRange)

保持對象完整消除過長方法 也有使用。

用方法替代參數

用方法替代參數 有以下兩個兩個場景:

  1. 方法中某個參數可以通過當前類內部的某個方法直接獲得
  2. 方法中某個參數可以通過另外一個對象參數的方法直接獲得
val basePrice = quantity * itemPrice
val discountLevel = getDiscountLevel()
val finalPrice = discountPrice(basePrice, discountLevel)

把discountLevel參數去掉,在discountPrice方法內部直接調用getDiscountLevel方法。

val basePrice = quantity * itemPrice
val finalPrice = discountPrice(basePrice)

之前有人反饋說內容有難度,今天的主題應該還好,不長而且比較輕松,希望小伙伴們能有所收獲,下一篇見。

推薦

解決萬惡之首“重復代碼”

消除過長方法

消除巨無霸類

答讀者問

你的參數列表像蚯蚓一樣讓人厭惡嗎

職責單一原則真的簡單嗎

查看《大話重構》系列文章,請進入YoyaProgrammer公眾號,點擊 核心技術,點擊 大話重構。

分類 大話重構

優雅程序員 原創 轉載請注明出處

圖片二維碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM