Рефакторизация программы по принципу единой ответственности - SOLID- SRP

Я изучаю SOLID и пытаюсь понять принцип единой ответственности.

Класс WalkingData хранит "дату" и "пройденное расстояние". Класс также читает сохраненные данные.

 public class WalkingData
    {
        public DateTime Date { get; set; }
        public int WalkedDistance { get; set; }
        private string _filePath = @"c:\Data\Json.txt";

        //Read Data from Json File
        public List<WalkingData> GetAll()
        {
            //If file does not exist returns an empty list
            if (!File.Exists(_filePath)) return new List<WalkingData>();

            string jsonData;

            //Read the existing Json file
            using (StreamReader readtext = new StreamReader(_filePath))
            {
                jsonData = readtext.ReadToEnd();
            }

            //Deserialize the Json and returs a list of WalkingData
            return JsonConvert.DeserializeObject<List<WalkingData>>(jsonData);            
        }

        //save an instance of  WalkingData in Json file
        public void Save()
        {
            List<WalkingData> lstExistingWalkingData = new List<WalkingData>();

            //if existing data, load it into lstExistingWalkingData
            if (File.Exists(_filePath))
                lstExistingWalkingData = GetAll();

            //Add the current instace into lstExistingWalkingData
            lstExistingWalkingData.Add(this);

            //Serialize lstExistingWalkingData
            string output = JsonConvert.SerializeObject(lstExistingWalkingData);

            //Save the Json file
            using (StreamWriter w = new StreamWriter(_filePath))
            {
                w.WriteLine(output);
            }
        }      
    }

После того, как я применил принцип единой ответственности, у меня есть новый код, который я хотел бы подтвердить, применил ли я этот принцип разумным образом:

//This class is located on a library called BOL and has a reference to DAL library
    public class WalkingData
    {
        public DateTime Date { get; set; }
        public int WalkedDistance { get; set; }
    }

    //This class is located on a library called BOL and has a reference to DAL library
    public class WalkingDataManager
    {        
        WalkingDataRepository walkingDataRepository = new WalkingDataRepository();

        public List<WalkingData> GetAll()
        {
            return walkingDataRepository.GetAll();
        }

        public void Save(WalkingData walkingData)
        {
            walkingDataRepository.Save(walkingData);
        }
    }

    //this class is located in library Called DAL
    internal class WalkingDataRepository
    {
        private string _filePath = @"c:\Data\Json.txt";

        //Read Data from Json File
        internal List<WalkingData> GetAll()
        {
            //If file does not exist returns an empty list
            if (!File.Exists(_filePath)) return new List<WalkingData>();

            string jsonData;

            //Read the existing Json file
            using (StreamReader readtext = new StreamReader(_filePath))
            {
                jsonData = readtext.ReadToEnd();
            }

            //Deserialize the Json and returs a list of WalkingData
            return JsonConvert.DeserializeObject<List<WalkingData>>(jsonData);
        }

        //save an instance of  WalkingData in Json file
        internal void Save(WalkingData walkingData)
        {
            List<WalkingData> lstExistingWalkingData = new List<WalkingData>();

            //if existing data, load it into lstExistingWalkingData
            if (File.Exists(_filePath))
                lstExistingWalkingData = GetAll();

            //Add the current instace into lstExistingWalkingData
            lstExistingWalkingData.Add(walkingData);

            //Serialize lstExistingWalkingData
            string output = JsonConvert.SerializeObject(lstExistingWalkingData);

            //Save the Json file
            using (StreamWriter w = new StreamWriter(_filePath))
            {
                w.WriteLine(output);
            }
        }
    }

1 ответ

Решение

Вы разделили ответственность за сохранение данных (WalkingDataRepository), а также заключил его в WalkingDataManager. Работа по рефакторингу полностью соответствует тому, что говорит SRP. Короче говоря, SRP - это не только нарушение функциональности, но и их инкапсуляция! Я тоже написал об этом статью.

Меня беспокоит анемия WalkingDataмодель. Это антипаттерн. Вы должны позволитьWalkingData взять на себя ответственность за поддержание собственных данных, а не за создание другого класса WalkingDataManager делать эту работу.

Другие вопросы по тегам