Можно ли использовать вторую часть этого кода для шаблонов репозитория и обобщений - PullRequest
2 голосов
/ 15 мая 2010

Есть ли проблемы с использованием версии 2, чтобы получить те же результаты, что и версия 1. Или это просто плохое кодирование.

Любые идеи

public class Customer
{
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    int Age { get; set; }
}

public interface ICustomer
{
    void AddNewCustomer(Customer Customer);
    void AddNewCustomer(string EmailAddress, int Age);
    void RemoveCustomer(Customer Customer);
}

public class BALCustomer
{
    private readonly ICustomer dalCustomer;
    public BALCustomer(ICustomer dalCustomer)
    {
        this.dalCustomer = dalCustomer;
    }

    public void Add_A_New_Customer(Customer Customer)
    {
        dalCustomer.AddNewCustomer(Customer);
    }

    public void Remove_A_Existing_Customer(Customer Customer)
    {
        dalCustomer.RemoveCustomer(Customer);
    }

}

public class CustomerDataAccess : ICustomer
{

    public void AddNewCustomer(Customer Customer)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }

    public void AddNewCustomer(string EmailAddress, int Age)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }

    public void RemoveCustomer(Customer Customer)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }


}

//          VERSION 2 

public class Customer_New : DataRespository<CustomerDataAccess>
{
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    public int Age { get; set; }
}

public class DataRespository<T> 
    where T:class,new()
{

    private T item = new T();
    public T Execute { get { return item; } set { item = value; } }
    public void Update()
    {
        //TO BE CODED
    }

    public void Save()
    {
        //TO BE CODED
    }

    public void Remove()
    {
        //TO BE CODED
    }
}    

class Program
{
    static void Main(string[] args)
    {
        Customer_New cus = new Customer_New()
        {
            Age = 10,
            EmailAddress = "this@demo.com"
        };

        cus.Save();
        cus.Execute.RemoveCustomer(new Customer());

        // Repository Version

        Customer customer = new Customer()
        {
            EmailAddress = "new@demo.com",
            CustomerID = 10
        };

        BALCustomer bal = new BALCustomer(new CustomerDataAccess());
        bal.Add_A_New_Customer(customer);
    }
}

Ответы [ 2 ]

1 голос
/ 27 июня 2010

У вас происходит много вещей, которые не имеют большого смысла.

Прежде всего, имена свойств всегда должны быть существительными (в единственном или множественном числе) или глаголом "существо", подобным Is * или Has *. Это свойства объекта, и они должны быть похожи на то, что вы сказали бы в ответ на вопрос типа «Не могли бы вы описать свой стол?» Execute - это операция, и поэтому она должна быть методом. Аналогично, ваши соглашения об именах в Версии 1 должны быть PascalCased, что означает отсутствие подчеркиваний, и первая буква всех слов должна быть заглавной. Это не несгибаемые истины, но они считаются ООП общими стандартами кодирования C #.

Во-вторых, код вашего основного метода на самом деле ничего не реализует в вашем обобщенном классе. Единственное, что на самом деле делает ваш класс, - это создание экземпляра CustomerDataAccess. Метод Save() ничего не будет делать, если только вы конкретно не сможете вызвать item.Save() Чтобы использовать функциональность «Сохранить, обновить, удалить» в вашем универсальном классе, ваш класс CustomerDataAccess должен будет реализовать интерфейс, ожидаемый ваш общий класс. Например:

public interface IDataAccess<T> : where T : YourBaseObject {
   public void Update(T item);
   public void Save(T item);
   public void Remove(T item);
}

public class Customer : YourBaseObject {
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    public int Age { get; set; }
}

public class CustomerDataAccess : 
    DataRespository<IDataAccess<Customer>> {
    public void PerformCustomerOnlyAction(Customer customer) { 
     /* do stuff */
    }
}

Теперь вы можете создать универсальный класс, который обрабатывает базовые функции CRUD, а все остальные функции доступны через свойство BaseRepository.

/* e.g. T = IDataAccess<Customer>, K = Customer */
public class DataRespository<T>
   where T : IDataAccess<K>, new()
   where K : YourBaseObject, new()
{

    private T _base;
    public T BaseRepository { 
          get { 
             if(_base == null)
                 _base = Activator.CreateInstance<T>(); 
             return _base;
          } 
    }
    public void Update(K item) { /* functionality for YourBaseObject */ }
    public void Save(K item) { /* functionality for YourBaseObject */ }
    public void Remove(K item) {  /* functionality for YourBaseObject */ }
}   

class Program
{
    static void Main(string[] args)
    {
        var repository = new CustomerDataAccess();
        Customer c = new Customer {
            Age = 10,
            EmailAddress = "this@demo.com"
        };
        repository.Save(c);
        // This pass-through is no longer needed, but shown as example
        // repository.BaseRepository.PerformCustomerOnlyAction(c);
        repository.PerformCustomerOnlyAction(c);
    }
}

ПРИМЕЧАНИЕ Я сделал вышеупомянутый код с нуля / памяти. Ограничения универсального типа могут работать не совсем так, как они у меня.

ASP.NET 3.5 Unleashed от Стивена Уолтера состоит из нескольких глав по созданию шаблона репозитория, который настроен аналогично тому, что вы пытаетесь выполнить в Версии 2. Он также разделяет обработку между уровень бизнес-логики и уровень доступа к данным. Хотя книга огромна (почти 2000 страниц) и многие примеры кода являются избыточными или лучше оставить их как часть компакт-диска, он достаточно глубоко разбирается в диапазоне от начального до среднего уровня. Он доступен на Amazon примерно за 25 долларов.

0 голосов
/ 15 мая 2010

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

  • Почему CustomerAccessLayer реализует интерфейс? Будет ли несколько слоев, реализующих этот интерфейс. Или, может быть, вы ожидаете, что любое поведение полиморфа от классов реализует этот интерфейс? Или, может быть, вы отделите интерфейс от отдельного модуля и обеспечите его функциональность через любой вид сервиса?
  • Зачем вам класс BALCustomer? Почему вы не можете совершать звонки напрямую на CustomerAccesLayer? И я уже говорил о CodeSile? :)
  • Если DataRepository имеет общее поведение и предоставит несколько AccessLayers, выбрасывают свойство Execute, почему у него есть свои собственные методы?

Думаю, можно продолжить ... Надеюсь, вы поняли мою точку зрения?

...