[英]Which is the better way of passing data to a Method
讓我們說我們有2個Expense1
和Expense2
。 哪個類實現比另一個更受歡迎,或者被認為更接近於面向對象?
我一直認為做Exp2.Calculate(1.5M,2)
比exp1.Calculate()
更具可讀性,並使用exp1 Class的屬性作為calculate方法的所需值。
Expense1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Expense1
{
public decimal ExpenseValue { get; set; }
public int NumberOfItems { get; set; }
private decimal result;
public decimal Result
{
get
{
return this.NumberOfItems * this.ExpenseValue;
}
}
public void Calculate()
{
this.result = this.ExpenseValue * this.NumberOfItems;
}
public void expense1()
{
this.ExpenseValue = 0;
this.NumberOfItems = 0;
}
}
Expense2
class Expense2
{
public decimal Calculate(decimal expenseValue, int numberOfItems)
{
return expenseValue * numberOfItems;
}
}
兩個類的實現
class Program
{
static void Main(string[] args)
{
Expense1 exp1 = new Expense1();
exp1.NumberOfItems = 2;
exp1.ExpenseValue = 1.5M ;
exp1.Calculate();
Console.WriteLine("Expense1:" + exp1.Result.ToString());
Expense2 exp2 = new Expense2();
string result = string.Empty;
result = exp2.Calculate(1.5M,2).ToString();
Console.WriteLine("Expense2:" + result);
Console.ReadKey();
}
}
Expense2
更容易閱讀和理解發生了什么,因為從調用中可以看出哪些參數被使用。
Expense1
可能有各種副作用,因為調用者在調用Calculate()
之前可能忘記設置用於計算的變量。
如果您需要訪問稍后用於計算結果的值,則可以使用類似的內容
public class Expense {
public decimal ExpenseValue { get; private set; }
public int NumberOfItems { get; private set; }
public decimal Result { get; private set; }
public decimal Calculate(decimal expenseValue, int numberOfItems) {
ExpenseValue = expenseValue;
NumberOfItems = numberOfItems;
Result = ExpenseValue * NumberOfItems;
return Result;
}
public Expense() {
Calculate(0, 0);
}
}
這將允許Expense
的內部狀態在對象的生命周期內保持一致,並定義它的Calculated
Expense2.Calculate
是確定性的(每次使用相同的參數調用時都具有相同的結果),並且因為它沒有副作用(參數被提供給它,而不是通過屬性),它也是線程安全的。 最后,它更簡單,更容易閱讀。
Expense1
是一個經典的OOP訓練 - 具有非線程安全狀態的殘骸,並且不保證Result
將返回線程調用Calculate
。 此外,閱讀和維護冗長且復雜。
我每次都喜歡Expense2
不是Expense1
。 我唯一要做的就是讓它變得靜止,因為必須創建一個Expense2
實例才能調用Calculate
。
我不喜歡Expense1一點。 我認為通常應該避免使用public get / set的屬性,因為它不提供封裝。 它甚至不比公共場地更好(雖然它確實為后面的防守條款提供了一些空間)。
然而,更糟糕的是,Calculate()方法是imo。 它不需要參數,但它仍然會改變對象的內部狀態。 目前尚不清楚如何。 同時,它寫入的字段result
不會被屬性Result
返回,該屬性再次執行相同的計算(如果必須進行計算,通常更喜歡某個屬性的方法)。
最后,沒有必要在構造函數中將基元類型初始化為其默認值,數字類型始終初始化為0。
===
費用2更好,更清楚發生了什么。 Method需要兩個名稱齊全的參數,並立即給出合理的結果。
但是,如果這個方法是該類的唯一用例,我會考慮重命名它,因為它不代表費用,它代表了一個接近費用計算器的東西。
這一切都取決於你想做什么,但經驗法則是當它們真正鏈接到對象時使用屬性,並在它們在對象外部時傳遞使用需要的參數。
一個簡單的例子,考慮將Person作為一個類,它的一個屬性是生日,所以在這種情況下你應該這樣做
public class Person{
public DateTime Birthday{get;set;}
public int GetAge(){
//some implementation
}
}
另一個例子,想想有一個Cube對象,並且在這個Cube對象中你有一個方法與另一個立方體相交,在這種情況下你應該將第二個立方體作為參數傳遞,而不是使它成為Cube的屬性,因為它是外部的東西。
public class Cube{
public Cube Intersect(Cube other){
//Do your logic here
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.