3

void を返すが引数の状態を変更する (つまり、非表示または暗黙の戻り値を提供する) メソッドは、一般的に悪い習慣ですか?

それらを嘲笑するのは難しいと思います。これは、おそらく悪い設計の兆候であることを示唆しています.

それらを回避するためにどのようなパターンがありますか?

非常に不自然な例:

public interface IMapper
{
    void Map(SourceObject source, TargetObject target);
}

public class ClassUnderTest
{
    private IMapper _mapper;

    public ClassUnderTest(IMapper mapper)
    {
        _mapper = mapper;
    }

    public int SomeOperation()
    {
        var source = new SourceObject();
        var target = new TargetObject();

        _mapper.Map(source, target);

        return target.SomeMappedValue;
    }
}
4

2 に答える 2

1

これを行うと、コードのテストがはるかに簡単になります。

public interface IMapper
{
    TargetObject Map(SourceObject source);
}

public class ClassUnderTest
{
    private IMapper _mapper;

    public ClassUnderTest(IMapper mapper)
    {
        _mapper = mapper;
    }

    public int SomeOperation(SourceObject source )
    {
        var target =  _mapper.Map(source, target);
        return target.SomeMappedValue;
    }
}

これで、マップ操作とSomeOperationを別々にテストできます。問題は、オブジェクトの状態をiddで変更すると、テスト用のスタブを提供するのが難しくなることです。新しいオブジェクトを返すときは、ターゲットのテストスタブを返し、呼び出し元のメソッドをテストできます。

于 2013-03-12T13:56:56.913 に答える
1

はい、ある程度まで。

あなたが説明するのは典型的な副作用です。理解する必要のある情報がコール スタックに含まれていないため、副作用によってプログラムが理解しにくくなります。追加情報が必要です。つまり、どのメソッドが以前に (そしてどのような順序で) 呼び出されたかなどです。

解決策は、副作用のないプログラムを作成することです。これは、変数、フィールドなどを変更しないことを意味します。代わりに、通常は変更するものの新しいバージョンを返します。

これは、関数型プログラミングの基本原則です。

もちろん、このプログラミング方法には独自の課題があります。I/O だけを考えてください。

于 2013-03-12T15:48:58.923 に答える