Создание слабосвязанной / масштабируемой программной архитектуры - PullRequest
7 голосов
/ 17 сентября 2010

Я исследовал это несколько недель. В настоящее время я занимаюсь проектированием слабосвязанной архитектуры с использованием n-уровневого (3-уровневого) метода и подхода к проектированию фабрики. Моя цель - поместить бизнес-логику каждого клиента (ClientA.DLL, ClientB.DLL) в отдельные пространства имен, чтобы проект масштабировался, то есть я могу изменять / удалять / добавлять бизнес-логику конкретного клиента, не затрагивая других, поскольку они не зависит друг от друга. Затем я вызываю пространства имен / класс клиента, используя уникальный идентификатор клиента (строковое значение, которое поддерживается в базе данных) через пространство имен Factory. Factory.DLL также скрывает логику для каждого клиента, в то время как BusinessAbstract.DLL служит в качестве макета или шаблона для классов каждого клиента. использование.

Вот проектное решение:

alt text

А вот фактический код:

BusinessAbstract.DLL

namespace BusinessAbstract
{
   // the entity / data transfer object
   public class MemberDTO
   {
      public string MemberID { get; set; }
      public string MemberName { get; set; }
    }

   // the interface
   public interface IMaintainable
   {
      void Add();
      void Edit();
      void Delete();
   }

  // the base abstract class, implements the Entity and the Interface
  public abstract class Member : MemberDTO, IMaintainable
  {
    // Implement IMaintanable but change it to abstract
    public abstract void Add();
    public abstract void Edit();
    public abstract void Delete();

    // a method with Database access, get from DAL
    public virtual MemberDTO GetMemberDetails(params object[] args)
    {
        return DAL.MemberDAL.FetchMemberDetails(args);
    }

    public virtual string GetClientBLL()
    {
        return "base's method";
    }
   }
 }

ClientA реализация AbstractBusinessRule

ClientA.DLL

 namespace ClientA
 {
    public class _Member : BusinessAbstract.Member
   {
       public override void Add()
      {
        throw new NotImplementedException();
      }

      public override void Edit()
      {
        throw new NotImplementedException();
      }

      public override void Delete()
      {
        throw new NotImplementedException();
      }

      public override string GetClientBLL()
      {
        return "ClientA Method";
      }
    }
 }

Фабрика

Factory.DLL

 public static class Invoker
 { 
     public static T GetMemberInstance<T>(string clientCode)
        where T : Member, IMaintainable
      {
        Type objType = Type.GetType(clientCode + "._Member," + clientCode);
        return (T)Activator.CreateInstance(objType);
      } 
  }

Пример реализации на уровне представления

Сайт

 protected void Page_Load(object sender, EventArgs e)
 {

    // invoke Member class using String hardcode
    Member obj = Invoker.GetMemberInstance<Member>("ClientA");
    Response.Write(obj.GetClientBLL()); //prints clientA method

    obj = Invoker.GetMemberInstance<Member>("ClientB");
    Response.Write(obj.GetClientBLL()); //prints clientB method

 }

И вы также заметите, что у меня есть папка DAL в каждой клиентской DLL, а также DLL AbstractBusinessRule, потому что я также хочу масштабировать слой DAL и использовать структуру слоя «UI-BLL-DAL».

Любые комментарии / предложения об этом дизайне приветствуются. Я надеюсь на вклад в то, как я могу улучшить эту структуру. Заранее спасибо.

Ответы [ 4 ]

1 голос
/ 17 сентября 2010

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

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

0 голосов
/ 17 сентября 2010

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

0 голосов
/ 17 сентября 2010

этот вопрос вышел слишком широким, нет единого лучшего для всех подхода.

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

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

У вас может быть набор основных правил и конфигурация по умолчанию, которая применяет набор этих правил к клиенту. Если вы делаете это в коде, при добавлении конфигурации клиента вы можете просто сказать .AddClient ("ClientA"), и он будет использовать только правила по умолчанию.

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

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

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

0 голосов
/ 17 сентября 2010

У вас есть основное нарушение принципа разделения задач / единой ответственности: ваши бизнес-объекты знают об их хранении.

Уровень данных 3-уровневой архитектуры должен отвечать за операции CRUD, иследует запрашивать для экземпляров объектов, которые нужны потребителям.Примерно так:

Presentation Layer ------- Data Layer
                              ||
                              ||
                       Business Layer

Это позволяет бизнес-уровню сконцентрироваться на реализации и исключает проблемы с постоянством.Если для уровня представления необходим новый бизнес-объект (для создания), он запрашивает уровень данных для него.

...