2010-10-01 3 views
4

Я работаю над своим первым настоящим приложением MVC, и я стараюсь следовать общим рекомендациям ООП. Я реорганизую простую бизнес-логику, которую я использовал в контроллере в моей модели домена. В последнее время я занимаюсь чтением, и кажется довольно ясным, что я должен поместить логику где-нибудь в классе сущности модели домена, чтобы избежать анти-шаблона «анонимной модели домена».ASP.NET MVC: Куда должна идти эта бизнес-логика?

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

Поэтому у меня есть классы сущностей в моей модели домена, которые выглядят так (упрощенно):

public class Customer 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
    bool IsMember { get; set; } 
} 

public class ParkingSpace 
{ 
    int ID { get; set; } 
    int Length { get; set; } 
} 

public class ParkingSpaceLease 
{ 
    int ID { get; set; } 
    DateTime OpenDate { get; set; } 
    DateTime CloseDate { get; set; } 
    Customer Customer { get; set; } 
    ParkingSpace ParkingSpace { get; set; } 
} 

Edit: Просто уточнить LeaseQuote это не класс сущности, как он используется только для отображения разбивка затрат на перспективных клиентов и не сохраняется нигде.

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

Так что это лучший способ сделать это? Имеет ли смысл создать новый объект ParkingSpaceLease внутри контроллера только, чтобы вызвать метод GetQuote на нем?

var lease = new ParkingSpaceLease(); 
var quote = lease.GetQuote(length: 168, isMember: true); 
return Json(quote); 

Или должен ли класс LeaseQuote иметь метод?

var leaseQuote = new LeaseQuote(); 
var quote = leaseQuote.GetQuote(length: 168, isMember: true); 
return Json(quote); 

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

Итак, куда должен идти метод GetQuote и зачем ему туда идти?

ответ

4

Это почти похоже на то, что ваш LeaseQuote не является сущностью и не является классом бизнес-уровня. Я имею в виду, вы не храните его в базе данных нигде, не так ли? И это не часть другого объекта данных.

Когда я вижу эту

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

Я думаю, что сигнатуры метода, как этот

public LeaseQuote GetQuote(Customer customer, ParkingSpace parkingSpace, int length) 

Но с этим в виду, я бы, вероятно, также хотят, чтобы хранить информацию о стоимости парковки в пределах ParkingSpace объекта и (если применимо) скидка клиента в организации Customer.

Куда бы это пошло? В классе модели (бизнес-модель, а не LINQ или модель Entity), которая обращается к вашим сущностям и служит поставщиком вашего контроллера.

Теперь я знаю, что вы не используете свои модели точно так же, как написано. И это может быть просто личная предвзятость. Но когда я думаю о моделях данных и объектах данных, у них не должно быть никаких аддонных методов вне того, что возвращается из базы данных. Они должны просто представлять данные без изменений, как они появляются в базе данных. Если вы действуете на данные, которые принадлежат к уровню над объектами данных.

Update:

Что мне любопытно из вашего примера, почему один хотел бы передать полные объекты Entity (Заказчик и парковочное место) по сравнению с только свойствами, необходимыми для выполнения расчета?

Это зависит от вашего кода. Выявление самого объекта может быть опасным, если код потребления управляет объектом. Я предпочитаю передавать объект главным образом потому, что это то, к чему я привык. Но я также стараюсь не манипулировать сущностью по пути. Это, и я думаю, что подпись метода отражает то, на что нацелен метод GetQuote; это связано с клиентом и парковочным местом.

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

Короткий ответ: Предпочтение.

+0

Вы правы в том, что LeaseQuote не является сущностью. Я должен был это ясно понять. Информация о покупке, дисконтном кредите и платеже будет отражена в транзакциях, которые происходят после фактического создания аренды, поэтому цель LeaseQuote - это просто отобразить разбивку для потенциальных клиентов. Что мне любопытно из вашего примера, почему нужно было бы передать все объекты Entity (Customer and Parking Space) вместо свойств, необходимых для выполнения расчета? –

+0

Figured :) Итак, да, поместите расчет либо в другой класс Model (возможно, LeaseManager, который также может иметь методы для добавления новых договоров аренды, удаления лизинга, обновления лизинга и т. Д.) Или установить его на вашем контроллере, если вы считаете, t использовать где-либо еще. – villecoder

+0

Не могли бы вы просто обратиться к моему вопросу о сигнатуре метода, принимающей объекты Entity, в отличие от значений свойств? Я отредактировал в вопросе, прежде чем вы отправили свой ответ! –

0

Просто сделайте GetQuote статическим методом в ParkingSpaceLease.

+0

Это ответ «не беспокойтесь об этом»? – jball

0

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

public class ParkingSpace 
{ 
    int ID { get; set; } 
    int Length { get; set; } 
    IEnumerable<ParkingSpaceLease> Leases { get; set; } 
    LeaseQuote GetQuote(Customer customer/*, other relevant parameters */) { ... } 
} 

public class ParkingSpaceLease 
{ 
    int ID { get; set; } 
    DateTime OpenDate { get; set; } 
    DateTime CloseDate { get; set; } 
    Customer Customer { get; set; } 
} 

public class LeaseQuote 
{ 
    //Properties 
    ParkingSpaceLease GetLease(); 
} 

EDIT я пропустил часть о LeaseQuote быть отдельный класс.

Смежные вопросы