簡體   English   中英

將數據傳遞給Method的更好方法是哪種

[英]Which is the better way of passing data to a Method

讓我們說我們有2個Expense1Expense2 哪個類實現比另一個更受歡迎,或者被認為更接近於面向對象?

我一直認為做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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM