Какова лучшая практика для архитектуры слоев? - PullRequest
0 голосов
/ 21 сентября 2011

Сейчас я работаю над очень крупным банковским решением, разработанным в VB6. Приложение в значительной степени основано на формах и не имеет многоуровневой архитектуры (весь код для доступа к данным, бизнес-логики и манипулирования формами находится в одном классе форм). Моя работа сейчас заключается в рефакторинге этого кода. Я пишу правильный уровень бизнес-логики и уровень доступа к данным в C #, а форма останется в VB.

Вот фрагменты кода:

public class DistrictDAO
{
    public string Id{get;set;}
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
    public DateTime SetDate { get; set; }
    public string UserName { get; set; }
    public char StatusFlag { get; set; }
}

Класс Entity Entity, почему его расширение - DAO, мне непонятно.

 public class DistrictGateway
{
    #region private variable
    private DatabaseManager _databaseManager;
    #endregion

    #region Constructor
    public DistrictGateway(DatabaseManager databaseManager) {
        _databaseManager = databaseManager;
    }
    #endregion

    #region private methods
    private void SetDistrictToList(List<DistrictDAO> dataTable, int index, DistrictDAO district){
        // here is some code for inserting 
    }    
    #endregion

    #region public methods
        try
        {
        /*
         query and rest of the codes
         */    

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }


    public void InsertDistrict() { 
        // all query to insert object
    }

    public void UpdateDistrict() { 

    }
    #endregion
}

Класс DistrictGateway, отвечающий за обработку запросов к базе данных Сейчас бизнес слой.

  public class District
{
    public string Id { get; set; }
    public string DistrictName { get; set; }
    public string CountryId { get; set; }
}


public class DistrictManager
{
    #region private variable
    private DatabaseManager _databaseManager;
    private DistrictGateway _districtGateway;
    #endregion

    #region Constructor
    public DistrictManager() { 
        // Instantiate the private variable using utitlity classes
    }
    #endregion

    #region private method
    private District TransformDistrictBLLToDL(DistrictDAO districtDAO) { 

        // return converted district with lots of coding here
    }

    private DistrictDAO TransformDistrictDLToBLL(District district)
    {

        // return converted DistrictDAO with lots of coding here
    }

    private List<District> TransformDistrictBLLToDL(List<DistrictDAO> districtDAOList)
    {

        // return converted district with lots of coding here
    }

    private List<DistrictDAO> TransformDistrictDLToBLL(List<District> district)
    {

        // return converted DistrictDAO with lots of coding here
    }


    #endregion

    #region public methods
    public List<District> GetDistrict() {
        try
        {
            _databaseManager.ConnectToDatabase();
          return TransformDistrictBLLToDL(  _districtGateway.GetDistrict());

        }
        catch (SqlException sqlException)
        {
            Console.WriteLine(sqlException.Message);
            throw;
        }
        catch (FormatException formateException)
        {
            Console.WriteLine(formateException.Message);
            throw;
        }
        finally {
            _databaseManager.ConnectToDatabase();
        }
    }

    #endregion

Это код бизнес-уровня.

Мои вопросы:

  1. Это идеальный дизайн?
  2. Если нет, то какие здесь недостатки?
  3. Думаю, этот код с дублированным блоком try catch
  4. Что может быть хорошим дизайном для этой реализации

Ответы [ 4 ]

0 голосов
/ 22 сентября 2011

Если ваша работа заключается в рефакторинге кода, то прежде всего спросите своего босса, должны ли вы действительно, просто рефакторинг или для добавления функциональности. В обоих случаях вам понадобится автоматизированный набор тестов для этого кода. Если вам повезло, и вы должны добавить к нему функциональность, то у вас по крайней мере есть отправная точка и цель. В противном случае вам придется выбирать отправную точку самостоятельно и не иметь цели. Вы можете рефакторинг кода бесконечно. Это может быть довольно сложно без цели.

Рефакторинг кода без тестов - рецепт для катастрофы. Рефакторинг кода означает улучшение его структуры без изменения его поведения. Если вы не проводите никаких тестов, вы не можете быть уверены, что не сломали что-либо. Поскольку вам нужно регулярно и много тестировать, то эти тесты должны быть автоматизированы. В противном случае вы тратите слишком много времени на ручное тестирование.

Устаревший код трудно вдавить в какой-нибудь тестовый комплект. Вам нужно будет изменить его, чтобы его можно было проверить. Ваше усилие обернуть тесты вокруг кода неявно приведет к некоторой многоуровневой структуре кода.

Теперь возникает проблема курицы и яйца: вам нужно провести рефакторинг кода, чтобы проверить его, но сейчас у вас нет тестов. Ответ заключается в том, чтобы начать с «защитных» методов рефакторинга и провести ручное тестирование. Вы можете найти более подробную информацию об этих методах в книге Майкла Фезера Эффективная работа с устаревшим кодом . Если вам нужно провести рефакторинг большого количества унаследованного кода, вам действительно следует прочитать его. Это настоящее сенсационное сообщение.

На ваши вопросы:

  1. Идеального дизайна не существует. Есть только потенциально лучшие.
  2. Если в приложении нет юнит-тестов, то это самый большой недостаток. Сначала введите тесты. С другой стороны: эти фрагменты кода не так уж и плохи. Похоже, что DistrictDAO чем-то напоминает техническую версию District. Возможно, была попытка ввести некоторую модель предметной области. И: По крайней мере, DistrictGateway получает DatabaseManager, введенный в качестве параметра конструктора. Я видел хуже.
  3. Да, блоки try-catch можно рассматривать как дубликаты кода, но в этом нет ничего необычного. Вы можете попытаться сократить предложения catch с разумным выбором классов Exception. Или вы можете использовать делегатов или некоторые методы АОП, но это сделает код менее читабельным. Подробнее см. этот другой вопрос .
  4. Вставьте устаревший код в какой-нибудь тестовый комплект. Лучший дизайн неявно появится.

Любым способом: прежде всего, уточнить, что ваш босс имеет в виду с помощью рефакторинга кода. Просто рефакторинг кода без какой-либо цели не будет продуктивным и не сделает босса счастливым.

0 голосов
/ 22 сентября 2011

Несмотря на то, что вы на самом деле не задаете здесь конкретный вопрос, похоже, вам может потребоваться общее руководство, чтобы вы пошли по правильному пути.Поскольку у нас нет глубокого представления о приложении в целом, как вы, было бы достаточно странно предложить единую методологию для вас.

n-уровневая архитектура кажется популярным вопросомнедавно, но это побудило меня написать серию блогов на нем.Проверьте эти ТАК вопросы и сообщения в блоге.Я думаю, что они вам очень помогут.

Серия блогов по N-уровневой архитектуре (с примером кода)

0 голосов
/ 22 сентября 2011

Для большого проекта я бы порекомендовал шаблон MVVM, чтобы вы могли полностью протестировать свой код, а позже будет гораздо проще расширить его или изменить его части. Даже вы сможете изменить пользовательский интерфейс, не меняя код в других слоях.

0 голосов
/ 21 сентября 2011

Идеально подходит?Нет такой вещи.Если вам нужно спросить здесь, это, вероятно, неправильно.И даже если он «идеален» прямо сейчас, это не будет разом, и энтропия овладеет им.

Мера того, насколько хорошо вы это сделаете, придет, когда придет время его расширять.Если ваши изменения проскочили, у вас все получилось.Если вам кажется, что вы боретесь с унаследованным кодом, чтобы добавить изменения, выясните, что вы сделали не так, и выполните рефакторинг.

Недостатки?Сложно сказать.У меня нет энергии, времени или мотивации, чтобы копать очень глубоко прямо сейчас.

Не могу понять, что вы подразумеваете под # 3.

Типичное наслоение будет выглядеть таксо стрелками, показывающими зависимости:

view <- controller -> service +-> model <- persistence  (service knows about persistence)

Для каждого слоя существуют сквозные проблемы:

  • представление знает о представлении, стилизации и локализации.Он делает все возможное, чтобы улучшить взаимодействие с пользователем, но не включает бизнес-правила.
  • Контроллер тесно связан с просмотром.Он заботится о связывании и проверке запросов от просмотра, маршрутизации к соответствующей службе, обработке ошибок и маршрутизации к следующему представлению.Вот и все.Бизнес-логика принадлежит сервису, потому что вы хотите, чтобы она была одинаковой для веб-сайтов, планшетов, мобильных устройств и т. Д.
  • Сервис - это место, где живет бизнес-логика.Он заботится о проверке в соответствии с бизнес-правилами и сотрудничестве с уровнями модели и персистентности для выполнения сценариев использования.Он знает о вариантах использования, единицах работы и транзакциях.
  • Объекты модели могут быть объектами значений, если вы предпочитаете более функциональный стиль, или вам предоставляется более богатая бизнес-логика, если вы так склонны.
  • постоянство изолирует все взаимодействия с базой данных.

Вы можете рассматривать такие сквозные проблемы, как безопасность, транзакции, мониторинг, ведение журналов и т. д., как аспекты, если вы используете такую ​​среду, как Spring, которая включает аспектно-ориентированное программирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...