N-уровневый дизайн для общего бизнес-уровня, но с разными уровнями представления и данных - PullRequest
1 голос
/ 25 ноября 2010

У меня есть приложение, которое существует в 3 разных уровнях представления: веб, мобильное (автономно) и настольное (автономно). Основные бизнес-объекты одинаковы для всех трех и имеют одинаковые правила проверки и бизнес-правила. Однако все они используют разные базы данных (веб - SQL Server 2008, мобильные / настольные - SQL Compact). Посредством процесса синхронизации настольные и мобильные приложения отправляют и получают данные из базы данных SQL 2008 сервера.

Я пытаюсь найти лучший n-уровневый подход, и я немного застрял. Я создал сборку для своих бизнес-объектов, которая инкапсулирует все бизнес-правила. Я бы очень хотел, чтобы у каждого объекта в этой сборке был метод Save (). Однако я не хочу, чтобы этот уровень знал о каком-либо конкретном уровне данных. По сути, я хочу, чтобы все три уровня представления заполняли эти объекты и вызывали метод Save (). Но я хочу, чтобы реализация метода Save () отличалась в зависимости от вызывающего приложения.

Сначала я создал интерфейс с именем IDataAdapter, а затем статическое свойство для каждого объекта для IDataAdapter. Затем метод Save () просто проверил, установлен ли он, и затем передал бизнес-объект его методу Save ().

public interface IDataAdapter
{
    void Save(BusinessProxy proxy);
}

public class BusinessProxy
{
    public IDataAdapter myAdapter { get; set; }

    public bool Save()
    {
        if (myAdapter == null)
            throw new Exception();
        myAdapter.Save(this);
    }
}

Конечно, это не идеально, потому что уровень представления должен был бы иметь ссылку на уровень данных, чтобы установить свойство Adapter. Мне бы очень хотелось иметь какую-нибудь систему плагинов, где я мог бы просто поменять data.dll в зависимости от платформы приложения.

Есть ли у кого-нибудь предложения о том, как реализовать это немного лучше?

Ответы [ 3 ]

1 голос
/ 25 ноября 2010

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

, где BusinessProxy может запросить использование своего IDataAdapter.

    public interface IDataAdapter
    {
        void Save(BusinessProxy proxy);
    }

    public class BusinessProxy
    {
        public static DataAdapterRegistry Adapter = new DataAdapterRegistry();

        public bool Save()
        {
            Adapter.Save(this);
            return true;
        }
    }

    public class DataAdapterRegistry : IDataAdapter
    {
        private Dictionary<Type, IDataAdapter> registry 
                                    = new Dictionary<Type, IDataAdapter>();

        public void Register(Type type, IDataAdapter adapter)
        {
            registry[type] = adapter;
        }

        public void Save(BusinessProxy proxy)
        {
            IDataAdapter adapter;
                if (registry.TryGetValue(proxy.GetType(), out adapter))
                   adapter.Save(proxy);
                else
                   throw new NotSupportedException(proxy.GetType().FullName);       
        }
    }

    class Customer : BusinessProxy
    {
    }

    class Order : BusinessProxy
    {
    }

    class Program
    {
        static void Main(string[] args)
        {
            BusinessProxy.Adapter.Register(typeof(Customer), new CustomerAdapter());
            BusinessProxy.Adapter.Register(typeof(Order), new OrderAdapter());

        }
    }

вы можете использовать инфраструктуру «инвертирования контейнера управления», такую ​​как spring.net, чтобы сделать это с файлами xml-configurtaion вместо жестко запрограммированной инициализации времени компиляции.

0 голосов
/ 25 ноября 2010

Вы можете использовать IoC (например, Structuremap ), чтобы зарегистрировать специальные реализации IDataAdapter в уровне представления.

Другим подходом может быть MEF , поэтому вы можете поменять сборки, когда захотите.

0 голосов
/ 25 ноября 2010

Я большой поклонник Simple.

Одна вещь, которую вы могли бы сделать, - просто выделить ваш метод Save для зависимой от платформы сборки. Просто сделайте его методом расширения, чтобы для вашего конечного пользователя он выглядел как часть их IDataAdapter. Просто, чисто.

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