5

私が作成しているアプリケーションでは、着信ジョブとそれらが実行されるまでの残り時間に関するデータを保持するスケジューラーが必要だったので、本来あるべきものとはかけ離れていると思う非常に単純な実装を作成しました。

実装

インターフェース

public interface IQueue
{
    string Name { get; set; }
    int Priority { get; set; }
}

クラス

public class TaskScheduler : Queue, IQueue
{
    public string Name { get; set; }
    public int Priority { get; set; }

    public TaskScheduler(string name, int priority)
    {
        Name = name;
        Priority = priority;
    }

    public void Add(string work, TimeSpan execution)
    {
        Enqueue(new Job {Work = work, Execution = execution});
    }

    public Job Get()
    {
        return (Job) Dequeue();
    }
}

public class Job
{
    public string Work { get; set; }
    public TimeSpan Execution { get; set; }

    public override string ToString()
    {
        return string.Format("{0} will be excuted in {1}", Work, Execution);
    }
}

使用法

    var schedulerss = new List<TaskScheduler>
                         {
                             new TaskScheduler("Meetings", 2), 
                             new TaskScheduler("Jobs", 1)
                         };

    schedulerss = schedulerss.OrderBy(element => element.Priority).ToList(); //ORDER THE schedulers according to the Priority

    schedulerss.Find(schedulers => schedulers.Name == "Meetings").Add("Meet Barack Obama", new TimeSpan(1, 0, 0, 15));
    schedulerss.Find(schedulers => schedulers.Name == "Jobs").Add("Make a cheese sandwich :D", new TimeSpan(0, 2, 0, 15));

    var meetingschedulers = schedulerss.Find(schedulers => schedulers.Name == "Meetings");

    if (null != meetingschedulers)
    {
        foreach (var job in meetingschedulers)
        {
            Console.WriteLine(job);
        }
    }

    Console.Read();

質問

このコードはうまく機能しますか、それともすべてを見逃しただけで、そのようなことを行うためのより良いアプローチがありますか?

リクエスト

私が提供したコードの欠点と、再利用されたより良いコードを作成するにはどうすればよいかについて、非常に詳細な回答をお願いします (このトピックが役立つと思われる他の人のために)。

4

2 に答える 2

2

使用法からわかるように、スケジューラー内にスケジューラーの名前があると、コードが少しファンキーになります...スケジューラーは本当に自分の名前を知る必要がありますか? 代わりにa を使用し、Dictionary<string, TaskScheduler>()そこに名前を入れます..

また、キューは常に を返すJobため、一般的なキューを使用する必要があります。Queue<Job>

私はいくつかの変更を加えました

実装

インターフェース

public interface IQueue
{
    int Priority { get; set; }
}

クラス

public class TaskScheduler : Queue<Job>, IQueue
{
    public int Priority { get; set; }

    public TaskScheduler(int priority)
    {
        Priority = priority;
    }

    public void Add(string work, TimeSpan execution)
    {
        Enqueue(new Job { Work = work, Execution = execution });
    }

    public Job Get()
    {
        return Dequeue();
    }
}

public class Job
{
    public string Work { get; set; }
    public TimeSpan Execution { get; set; }

    public override string ToString()
    {
        return string.Format("{0} will be excuted in {1}", Work, Execution);
    }
}

使用法

        var schedulers = new Dictionary<string, TaskScheduler>();

        schedulers.Add("Meetings", new TaskScheduler(2));
        schedulers.Add("Jobs", new TaskScheduler(1));

        schedulers["Meetings"].Add("Meet Barack Obama", new TimeSpan(1, 0, 0, 15));
        schedulers["Jobs"].Add("Make a cheese sandwich :D", new TimeSpan(0, 2, 0, 15));

        if (schedulers.ContainsKey("Meetings"))
        {
            foreach (var job in schedulers["Meetings"])
            {
                Console.WriteLine(job);
            }
        }

その他の提案

あなたは複数のスケジューラーを扱っているので、優先順位付けや追加したいその他のものを処理する、ある種の schedulerController を作成することをお勧めします。

リクエストごとに例を編集

あなたがスケジューラで何をしたいのか正確にはわかりませんが、私は次のようなユーティリティクラスを意味していました:

public class TaskSchedulerController
{
    private Dictionary<string, TaskScheduler> _scedulers;

    public TaskSchedulerController()
    {
        _scedulers = new Dictionary<string, TaskScheduler>();
    }

    public void Add(string name, int priority)
    {
        _scedulers.Add(name, new TaskScheduler(priority));
    }

    public IEnumerable<string> GetJobsOfScheduler(string name)
    {
        if (_scedulers.ContainsKey(name))
        {
            foreach (var job in _scedulers[name])
            {
                yield return job.ToString();
            }
        }
    }
}
于 2013-07-20T17:29:59.027 に答える
0

あなたの抽象化にはいくつかの問題があります...キューを抽象化しているように見えますが、Job クラスは抽象化していないようです。これは逆でなければなりません (そうでなければ、少なくともあなたの人生はずっと楽になります)。

public interface IJob
{
    MyJobType Type{ get; set; }
    string Name { get; set; }
    int Priority { get; set; }
    void RunJob();
}
  1. とにかく使用していないので、IQueueを削除できます。

  2. #3 で解決できない正当な理由がない限り、1 つのキューのみを使用してください

  3. ジョブ クラスを抽象化します。結局のところ、チーズ サンドイッチを作成するジョブは、会議を処理するジョブと同じではありません。上記のインターフェースのようなものを使用すると、タイプ (作成した列挙) と優先順位でジョブを並べ替え、IJob.RunJob を使用して実行できます。各実装でジョブが実際に何をするかを知る必要はありません。

于 2013-07-20T16:53:31.003 に答える