1

class Person、2つの子クラスStaff、およびStudentinterface がありますIPerson。また、クラスDatabaseとクラスがありGatewayます。クラスDatabase

private string name = "username";

と方法

public void getName() {return id;}

Staff と Student の両方に getName() メソッドがあります。ゲートウェイを介して、学生とスタッフのクラスからデータベースへのリクエスト getName() を作成する必要があります。クラス Gateway は、メソッド getName() がStaff( then return id) またはStudent( then return "Go away!") によって要求されたかどうかを確認する必要があります。誰でもそれで私を助けてくれませんか。Gatewayクラスのインターフェースとして使おうと思ってDatabaseいたのですが、C#の勉強しかしていないのでどうすればいいのかわかりません。または、これを行うためのより良い方法があるかもしれません...助けてくださいありがとう

ここにいくつかのコードがあります:

public class Staff : Person
  {


    public Staff() {}
    public Staff(string id): base(id) {}
    public override string getName()
    {
        throw new NotImplementedException();
    }
    public override void Update(object o)
    {
      Console.WriteLine(id + " notified that {1}", id, o.ToString()); 
    }
    public override void UpdateMessage(object p)
    {
      Console.WriteLine(id + " notified about new message in chat: {1}", id, p.ToString()); 
    }
  }

public class Student : Person
{
    public Student() {}
    public Student(string id): base(id) {}
    public override string getName()
    {
        throw new NotImplementedException();
    }
    public override void Update(object o) 
    {
     Console.WriteLine(id +"  notified that {1}", id, o.ToString());
    }
    public override void UpdateMessage(object p) 
    {
     Console.WriteLine("Message for " + id + "  {1}", id, p.ToString());
    }
}

 public abstract class Person : IPerson
{
    public string id;
    public Person() { }
    public abstract string getName();
    public Person(string i) { this.id = i; }
    public abstract void Update(Object o);
    public abstract void UpdateMessage(Object p);
}

public interface IPerson     
 {
   void Update(Object o);
   void UpdateMessage(Object p);
   string getName();
 }

 class database
 {
     public string username = "username";
     private string name =  "user details";
     private string grade = "user grade";

     public string getName(Object o)
     {
         if (o is Staff) { return name; }
         else { return "Go away!"; }
     }
     public string getgrade() { return grade; }
 }


 public class Gateway
   {
    public void DoSomethingWithPerson(IPerson person)
    {
        string iD = person.getName();
        if (person is Student)
        {
            return "go away!";
        }
        else if (person is Staff)
        {
            return name;
        }
    }
}
4

2 に答える 2

2

これはやや複雑な質問です。最初に、C# のスタイルの問題をいくつか指摘したいと思います。

  • クラスdatabaseは小文字ですが、残りは一貫して大文字と小文字が区別されます。一部のメソッドには一貫性がありません (たとえば、慣用的な PascalCase を使用するメソッドもあれば、camelCase または小文字を使用するメソッドもあります)。
  • IPersonStaffのインスタンスをStudentとして渡すことができPerson、基本的に今と同じ方法ですべてを使用できるため、実際にはここでは目的がありません。ほとんどの場合、両方ではなく、インターフェイスまたは抽象基本クラスのいずれかを選択する必要があります。
  • C# には「プロパティ」という概念があり、これは基本的にゲッターとセッターにとって便利な構文です。これは、バッキング フィールドの実装を非公開に保つことができるため、パブリック フィールド (クラスやinなど) よりも優先さpublic string usernameれます。これの構文は、デフォルトの実装が必要な場合です。これをより複雑なものに拡張できます。たとえば、ユーザー名がトリミングされていることを確認したい場合があります。(1)databasepublic string idPersonpublic string username { get; set; }
  • 些細な問題ですが、通常objectは小文字の o が使用されます。
  • .ToString()実際には、文字列フォーマットの補間でオブジェクトを呼び出す必要はありません。(2)

(1)

private string m_username;
public string username {
    get { return m_username; }
    set { m_username = (value != null ? value.Trim() : value); }
}

(2) これらの行は等価です。

Console.WriteLine(id + " notified that {1}", id, o.ToString());
Console.WriteLine("{0} notified that {1}", id, o);

それでは問題に進みます。私には、クラスごとに異なる動作が必要なように思えます。言い方からすると、これはアクセス/許可の問題のように聞こえます。データ ストアの設定方法によっては (この場合、コードでは定数のように見えますが、ある種のクエリを簡単に実行できます)、次のようなことができます...

[Flags]
public enum Permission {
    None = 0,
    GetName = 1
}

public abstract class Person {
    /* ... */
    public abstract Permission Permissions { get; }
}

public class Staff : Person {
    /* ... */
    public override Permission Permissions {
        get { return Permission.GetName; }
    }
}

public class Student : Person {
    /* ... */
    public override Permission Permissions {
        get { return Permission.None; }
    }
}

public class Database {
    /* ... */
    private Dictionary<string, string> NamesDatabase { get; set; }
    public string getName(string id) {
        // As a consequence of being managed by Gateway, assume that the caller has access
        return NamesDatabase[id];
    }
}

public class Gateway {
    public string DoSomethingWithPerson(Person person, string desiredNamePersonId) {
        if (person.Permissions.HasFlag(Permission.GetName)) {
            Database db = new Database();
            return db.getName(desiredNamePersonId);
        }
        return "go away!";
    }
}

そのようなコンストラクタがあるとDatabaseします:

    public Database() {
        NamesDatabase = new Dictionary<string, string>(2);
        NamesDatabase["id1"] = "Student Amy";
        NamesDatabase["id2"] = "Staff Mary";
    }

そして、Mainそのようなもの:

    static void Main() {
        Gateway gate = new Gateway();
        Console.WriteLine("Student id1 looks up Staff id2: {0}", gate.DoSomethingWithPerson(new Student("id1"), "id2"));
        Console.WriteLine("Staff id2 looks up Student id1: {0}", gate.DoSomethingWithPerson(new Staff("id2"), "id1"));

        Console.ReadLine();
    }

出力は次のとおりです。

 Student id1 looks up Staff id2: go away!
 Staff id2 looks up Student id1: Student Amy

不明な点がある場合、または評価の点から外れている場合は、お気軽に明確な質問をしてください。

于 2013-05-11T09:15:51.960 に答える