まず最初に、デメテルの法則にentity.underlyingEntity.underlyingEntity.method()
よると、次のようなことを行うことはコードのにおいと見なされます。このようにして、実装の詳細の多くを消費者に公開しています。そして、そのようなシステムの拡張または修正の各ニーズは多くのことを傷つけます。
そのため、CodesInChaosのコメントに従って、HasRole
またはのIsAdmin
メソッドを使用することをお勧めしますUser
。このように、ユーザーにロールを実装する方法は、コンシューマの実装の詳細のままです。また、ユーザーに自分の役割の詳細について尋ねてから、それに基づいて決定するのではなく、自分の役割が何であるかをユーザーに尋ねる方が自然です。
string
必要な場合を除き、sの使用も避けてください。内容は事前に不明であるため、変数のname
良い例ですstring
。一方、role
コンパイル時によく知られている2つの異なる値がある場合は、厳密な型指定を使用することをお勧めします。それが列挙型の出番です...
比較する
public bool HasRole(string role)
と
public enum Role { Admin, User }
public bool HasRole(Role role)
2番目のケースでは、何を渡すべきかについて、より多くのアイデアを得ることができます。またstring
、ロール定数がわからない場合に誤って無効な値を渡すことを防ぎます。
次に、ロールの外観を決定します。ユーザーに直接保存されている列挙型を使用できます。
public enum Role
{
Admin,
User
}
public class User
{
private Role _role;
public bool HasRole(Role role)
{
return _role == role;
}
// or
public bool IsAdmin()
{
return _role == Role.Admin;
}
}
一方、ロールに動作自体を持たせたい場合は、そのタイプがどのように決定されているかの詳細を再び隠す必要があります。
public enum RoleType
{
User,
Admin
}
public class Role
{
private RoleType _roleType;
public bool IsAdmin()
{
return _roleType == RoleType.Admin;
}
public bool IsUser()
{
return _roleType == RoleType.User;
}
// more role-specific logic...
}
public class User
{
private Role _role;
public bool IsAdmin()
{
return _role.IsAdmin();
}
public bool IsUser()
{
return _role.IsUser();
}
}
ただし、これは非常に冗長であり、ロールを追加するたびに複雑さが増します。通常、デメテルの法則を完全に順守しようとすると、コードが最終的にこのようになります。モデル化するシステムの具体的な要件に基づいて、設計を改善する必要があります。
あなたの質問によると、enumを直接オンにした最初のオプションを使用した方が良いと思いますUser
。でさらにロジックが必要なRole
場合は、2番目のオプションを開始点として検討する必要があります。
User.HasRole(Role.Admin)
です。