3

したがって、正常に保存されたばかりのエンティティを返さない Save メソッドがあるのは少し奇妙だと思います。ただし、Save に渡されるエンティティは関数によって変更されます。

例:

//T SaveOrUpdate(T entity); from IDao
PlaylistDao.SaveOrUpdate(playlist);

この関数は、プレイリストを取得してデータベースに保存し、保存したプレイリストを返します。ただし、SaveOrUpdate に渡されるパラメーターは、その戻り値と等しい参照です。

これを念頭に置いて、より明確な実装です。

public void SavePlaylist(Playlist playlist)
{
    try
    {
        NHibernateSessionManager.Instance.BeginTransaction();
        PlaylistDao.SaveOrUpdate(playlist);
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        throw;
    }
}

public Playlist SavePlaylist(Playlist playlist)
{
    Playlist savedPlayist;
    try
    {
        NHibernateSessionManager.Instance.BeginTransaction();
        savedPlayist = PlaylistDao.SaveOrUpdate(playlist);
        NHibernateSessionManager.Instance.CommitTransaction();
    }
    catch (Exception exception)
    {
        Logger.Error(exception);
        throw;
    }

    return savedPlayist;
}

前にコードを見たことがない人にとっては、2 番目の関数の方がわかりやすいと思いますが、開発者が理解すれば、最初の実装の方が簡潔でわかりやすいと思います。何かご意見は?

更新:明確にするために、SaveOrUpdate にはプレイリストに副作用があります。プレイリストがデータベースに保存されると、その ID フィールドが DB から提供された値で更新されます。

4

5 に答える 5

4

私は最初の方法に行きますが、小さな変更を加えて、引数を で渡しますref。(コメントを参照してください。) 2 番目の問題は、余分な変数を不必要に作成していることです。最初のメソッドにいくつかのタグを追加<summary>して、インテリセンスで何が起こるかを示して、混乱を明確にしてみませんか? 私にとって、これは本質的に同じことをするために追加の変数を作成するよりも優れています。

于 2012-12-05T06:34:50.213 に答える
1

これはより好みに基づいていると思います。重要なことは、1 つのモデルを選択してそれに固執することです。

私の個人的な意見では、2 番目の方法が最適です。これが私の理由です。

  • Save メソッドには副作用があります。つまり、渡されたオブジェクトが変更されます。これらの変更は、保存メソッドを実際に調べずに、コードを読んだ人には完全に表示されない可能性があるオブジェクト参照を介して呼び出し元に返されます。

最初の行は、次の行よりも変更されたオブジェクトのアイデアを伝えていると思います

// Side effect is better understood
paylist = PlaylistDao.SaveOrUpdate(playlist);

// Side effect is not obvious unless looked into the SaveOrUpdate method.
PlaylistDao.SaveOrUpdate(playlist);

これが、関数型言語は副作用を許容せず、変更された値を返すことを強制するため、手続き型言語よりも関数型言語を好む人がいる理由です。関数型言語を使用していなくても、そのパターンに従うことには利点があると思います。

  • その他の理由は、変更された値を返すことで、より使いやすい流暢な API を構築できることです (ただし、Playlist クラスにメソッドを追加する場合のみ、これは DAO に SaveOrUpdate メソッドがある場合には当てはまりません)。 .

たとえば、メソッドから常に新しいオブジェクトを返す場合は、次のような呼び出しを行うことができます。

playlist.SaveOrUpdate().WriteToLog(); // Something like this.
于 2012-12-05T06:52:49.453 に答える
1

最初のメソッドでは、パラメータ値を返すだけで、副作用はまったくありません。明確でも有用でもないと思います。2 番目の方法の方が便利なようです。

編集:コメントに基づいています。

あなたの方法はそのようなことをすべきではないと思いますSaveOrUpdate。値を返す方が良いです。例外が発生した場合、または予期しない状況が発生した場合はどうなりますか:

playerlist = null;

メソッドでは、SaveOrUpdateメソッド内の元のオブジェクトへの影響は見られませんSavePlaylist。オブジェクト参照は値で渡されるため:)。2番目の方法では、オブジェクトに影響を与え、それがより明確に反映されます。refパラメータをキーワードで渡すと、最初の方法がより明確になります。

于 2012-12-05T06:34:10.573 に答える
0

ブール値を返す方が良いでしょうか?問題の場合は false ? 戻り値を簡単に確認できます

于 2012-12-05T06:36:24.033 に答える
-1

2 回目の試行では、システムに 2 つのリストが残ります。無効なエントリを含む Playlist と、有効なエントリを含む savedPlaylist (有効 = 現在)。おっと、例外が発生すると、savedPlaylist は無効になり、Playlist は引き続き有効になります... 問題が発生しましたか?

最初の試行では、常に現在の値を持つプレイリストが残されます。すべてが保存されて更新され、新しいインスタンスに一意の ID などが付けられるか、何も変更されずにリストに保存されていないデータが含まれているかのいずれかです。

ところで: PlayList が参照によって渡されるとは思いません。リスト インスタンス自体は変更されず、その内容のみが変更されます。また、インスタンス自体が変更されたとしても、メソッド自体がパラメータ 'Playlist' を入力のみとして宣言しているため、これらの変更はメソッドの外では見えません。

于 2012-12-05T06:55:41.690 に答える