簡體   English   中英

我如何最好地重構這個C#代碼?

[英]How do I best refactor this C# code?

我想重構以下代碼,如何注入通知處理程序? 最小的原始代碼更改和必要時的最佳重構。

public class TestEventHandlers
{
    public TestEventHandlers() { }

    public void OpenMarket(Page page)
    {
        var Id = page.Request["MarketId"];

        var repository = new EntityRepository();
        IEntity market = repository.GetById(Id);

        if (market.State != "Open")
        {
            throw new Exception("The market is not open!");
        }
        else
        {
            market.Open();

            repository.SaveChangesTo(market);

            var smtpClient = new SmtpClient();

            var message = new MailMessage();
            message.Subject = "market open";
            message.Body = market.ToString() + " was open.";
            message.To.Add(new MailAddress("market@mail.com"));

            smtpClient.Send(message);
        }
    }

    public void CloseMarket(Page page)
    {
        var Id = page.Request["MarketId"];
        var repository = new EntityRepository();
        IEntity market = repository.GetById(Id);

        if (market.State == "Close")
        {
            throw new Exception("The market is already close!");
        }
        else
        {
            market.Close();

            repository.SaveChangesTo(market);

            var smtpClient = new SmtpClient();

            var message = new MailMessage();
            message.Subject = "market closed";
            message.Body = market.ToString() + " has been closed.";
            message.To.Add(new MailAddress("market@mail.com"));

            smtpClient.Send(message);
        }
    }
}

我已經像下面那樣重構了它 -

public class TestEventHandlers
{
        public TestEventHandlers() { }

        public void OpenMarket(Page page)
        {
            var Id = page.Request["MarketId"];
            if (id!=null)
            { 
            var repository = new EntityRepository();
            IEntity market = repository.GetById(Id);

            if (market.State != "Open")
            {
                throw new Exception("The market is not open!");
            }
            else
            {
                market.Open();

                repository.SaveChangesTo(market);

                SendEmailNotification("market open", market.ToString() + " was open.", "market@mail.com");
            }
           }
          else
            {
                throw new Exception("Id can not be null");
            }
        }

        private static void SendEmailNotification(string subject,string body,string emailAddress)
        {
            var smtpClient = new SmtpClient();

            var message = new MailMessage();

            message.Subject = subject;
            message.Body = body;
            message.To.Add(new MailAddress(emailAddress));

            smtpClient.Send(message);
        }

        public void CloseMarket(Page page)
        {
            var Id = page.Request["MarketId"];
            if(id!=null)
            {
            var repository = new EntityRepository();
            IEntity market = repository.GetById(Id);

            if (market.State == "Close")
            {
                throw new Exception("The market is already close!");
            }
            else
            {
                market.Close();

                repository.SaveChangesTo(market);

                SendEmailNotification("market closed", market.ToString() + " has been closed.", "market@mail.com");
            }
        }
           else
            {
                throw new Exception("Id can not be null");
            }
       }
    }

試試這個@Neo

public class TestEventHandlers
{
    public void OpenMarket(Page page)
    {
        ChangeMarketState(page, "Open", "market@mail.com");
    }

    public void CloseMarket(Page page)
    {
        ChangeMarketState(page, "Close", "market@mail.com");
    }

    private static void SendEmailNotification(string subject,string body,string emailAddress)
    {
        var smtpClient = new SmtpClient();

        var message = new MailMessage();

        message.Subject = subject;
        message.Body = body;
        message.To.Add(new MailAddress(emailAddress));

        smtpClient.Send(message);
    }

    public void ChangeMarketState(Page page, string changeStateTo, string sendMailTo)
    {
        var Id = page.Request["MarketId"];
        if(Id != null)
        {
            var repository = new EntityRepository();
            IEntity market = repository.GetById(Id);

            if (market.state == changeStateTo)
            {
                if(changeStateTo == "Close")
                    throw new Exception("The market is already close!");
                else
                    throw new Exception("The market is not open!");
            }
            else
            {
                string currentMarketState = string.empty;
                string mailHeader = string.empty;
                if(changeStateTo == "Close")
                {
                   market.Close();
                   currentMarketState = market.ToString() + " has been closed.";
                   mailHeader = "market closed";
                }
                else
                {
                   market.Open();
                   currentMarketState = market.ToString() + " was open.";
                   mailHeader = "market open";
                }

                repository.SaveChangesTo(market);

                SendEmailNotification(mailHeader, currentMarketState, sendMailTo);
            }
        }
        else
        {
            throw new Exception("entityId can not be null");  
        }
    }
}

我會用這樣的東西:

public interface INotifier
{
    void SendEmailNotification(string subject, string body, string emailAddress);
}

public class Notifier : INotifier
{
    public void SendEmailNotification(string subject,string body,string emailAddress)
    {
        var smtpClient = new SmtpClient();

        var message = new MailMessage();

        message.Subject = subject;
        message.Body = body;
        message.To.Add(new MailAddress(emailAddress));

        smtpClient.Send(message);
    }
}

public class TestEventHandlers
{       
    public INotifier Notifier { get; set; }

    public TestEventHandlers()
    {           
        Notifier = new Notifier();
    }

    public void OpenMarket(Page page)
    {
        var Id = page.Request["MarketId"];
        if (id!=null)
        { 
            var repository = new EntityRepository();
            IEntity market = repository.GetById(Id);

            if (market.State != "Open")
            {
                throw new Exception("The market is not open!");
            }
            else
            {
                market.Open();

                repository.SaveChangesTo(market);

                Notifier.SendEmailNotification("market open", market.ToString() + " was open.", "market@mail.com");
            }
        }
        else
        {
            throw new Exception("entityId can not be null");
        }           
    }

    public void CloseMarket(Page page)
    {
        var Id = page.Request["MarketId"];
        if(id!=null)
        {
            var repository = new EntityRepository();
            IEntity market = repository.GetById(Id);

            if (market.State == "Close")
            {
                throw new Exception("The market is already close!");
            }
            else
            {
                market.Close();
                repository.SaveChangesTo(market);
                Notifier.SendEmailNotification("market closed", market.ToString() + " has been closed.", "market@mail.com");
            }
        }
        else
        {
            throw new Exception("entityId can not be null");
        }
    }       
}

在這種情況下,您的INotifier默認為構造函數的常規實現,但在需要時可以使用訪問器覆蓋。 如果您希望在不進行測試時始終注入依賴項,則只需向構造函數添加參數即可。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM