Not sure if I have the correct terminology, but I am a little confused on how to set up my 3-tier system.
Lets say I have a table of Users in my DB.
In my DAL, I have a UserDB class that calls stored procs into he DB to insert, update, delete.
I also have a UserDetails class that is used in UserDB to return and pass in objects.
So now I am not sure how to use this in my Business Logic Layer. Do I need another BLL object class for users? If so, would this not be redundant?
Or do I just use the UserDetails class throughout my BLL?
Look up a concept called 'Domain Driven Design' - the biggest thing there is using what's called a repository pattern (such as your UserDB class) as an adapter to the database, as well as a factory. Your business objects, or domain objects, then incorporate business logic into themselves and can handle interactions with other business objects.
What technology are you using? Something like ActiveRecord can probably help you a lot.
You typically would enforce Business Rules in your BLL. For example, you might allow regular call center employees to offer a 10% discount on new service but allow a manager to offer a 20% discount. You would have a business rule in your BLL that goes something like:
// Pseodocode
double Discount
{
set
{
if (value > 10% AND Employee Is Not Manager) then throw Exception
if (value > 20%) then throw Exception
discount = value;
}
}
You can use following design:
DAL:
namespace DAL.Repository
{
public class UsersRepository
{
public static IList GetUser(string UserId)
{
using(MyDBEntities context=new MyDBEntities())
{
// it calls SP in DB thru EF to fetch data
//here you can also context.user to fetch data instead of SP
return context.GetUser(UserId).ToList();
}
}
}
}
BLL
namespace BLL
{
public class User
{
public static IList GetUser(string UserId)
{
return DAL.Repository.UserRepository.GetUser(UserId);
}
}
}
PL
ddlUser.DataTextField = "UserName";
ddlUser.DataValueField = "UserId";
ddlUser.DataSource= BLL.User.GetUser(string.Empty);
ddlUser.DataBind()
Note: while sending data from BL to PL converting DB Entity to Business entity is required if you want to loop thu data in PL.
Related
I'm having slight trouble figuring out how to make my design loosely coupled. Specifically how to implement business logic and rules into domain models, as well as where to place the different parts of the code - i.e. folder structure.
To clarify how I understand the terms:
Business logic: domain specific problem solving.
Business rules: domain specific rules.
Domain model: abstractions of domain specific, real world objects e.g. an employee.
So, let's do a simple example
Say we have a company with employees. Every employee must have a security number (business logic). The security number must be at least 10 characters long (business rule).
My shot at modeling this would look something like:
# Conceptual model of an employee within the company
class Employee {
private $name;
private $securityNumber;
// Business logic
public function setSecurityNumber(string $securityNumber,
SecurityNumberValidatorInterface $validator) {
if($validator->validateSecurityNumber($securityNumber)) {
$this->securityNumber = $securityNumber;
} else {
throw new \Execption("Invalid security number");
}
}
}
# Setup interface that corresponds to the business logic
interface SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool;
}
# Time to implement the business logic that is compliant with the rule
class SecurityNumberValidator implements SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool {
$valid = false; // control variable - ensuring we only need a single return statement
$length = strlen($validateThisSecurityNumber);
if ($length < 10) {
$valid = true;
}
return $valid;
}
}
I see some problems with this approach...
Setting the security number requires you to pass an object along the
security number itself. Which I think looks a bit nasty for a setter.
Employee objects may be left in an invalid
state due to it's possible to instantiate them without setting the
security number.
To solve the second problem, I can just create a constructor for the Employee class like the one below
public function __constructor(string $name,
string $securityNumber,
SecurityNumberValidatorInterface $validator) {
$this->name = $name;
$this->setSecurityNumber($securityNumber, $validator);
}
This may be an antipattern due to calling a setter in the constructor...
What is a nicer approach to this? Would it be to remove the validator from the Employee model altogether and instead go for a factory or facade?
Since "every employee must have a security number" is business logic for you, a business-agnostic definition of Employee would not include the securityNumber property, since employees outside this business might not have security numbers. Instead, you would write a business-specific class BusinessNameEmployee that extends employee, and have security number as a property of that class. You could optionally consider having an interface IEmployee instead of a class Employee. Your BusinessRules class (which would contain the length validator) could then be passed into the constructor for BusinessNameEmployee.
There is way call value object, that's part of an entity. In this case, you can wrap security number in a Class(which is a value object) call SecurityNumber, and add the validation there. You can refer to this example: https://kacper.gunia.me/ddd-building-blocks-in-php-value-object/
In DDD, there is a anti-pattern call Primitive Obsession, your mind may be deep in this trap.
Doubt about where to define the actions that are going to act on attributes of one class?
Ex:-Account is a class where we going to define attributes of account like account no,holder name.
As usual Employee(class) of the Bank can add,update(crud) operation on customer's account.
My doubt is in which class we have to define those (crud)actions either in Employee class or in Account class?.
Because these operations are performed by employee in real time.On the other hand,Actions need to act on Account attributes may define in Account class itself,which is the better one?
'Actions need to be performed on attributes ,defined in same class is better' or 'Actions are defined in class with respect to whose actions are they(actors) is better'?
In my understanding of the problem you describe, such "operations" go in the service layer.
You can see in the link I shared above that Martin Fowler describes the service layer as:
Defines an application's boundary with a layer of services that
establishes a set of available operations and coordinates the
application's response in each operation.
So, in my view of your solution, both Employee and Account are just POJOs like #Rotka said. In my view the interfaces for your layers would be somewhat like
At the data source layer:
interface AccountRepository {
Account findById(Long id);
Account save(Account account);
}
And I doubt that you can delete a bank account, you could put it a state of inactivity though.
Than your service layer could be somewhat like
interface AccountService {
Account openAccount(Account account);
void closeAccount(Account account);
transferFunds(Account source, Account target);
...
}
What you call employee is probably the wrong abstraction to use here. You probably think in terms of users, like is the current user allowed to open accounts?
So, consider the following hypothetical implementation
class DefaultAccountService implements AccountService {
private SecurityContext securityContext;
private Validator validator;
private AccountRespotiroy accountRepository;
#Override
public Account openAccount(Account account) {
if(!securityContext.getUser().hasPermission("openAccount")){
throw new UnAuthorizedException("You cannot open accounts");
}
Set<ConstraintViolation> violations = validator.validate(account);
if(violations.size() > 0){
throw new BadRequestException("Invalid account", violations);
}
return accountRepository.save(account);
}
...
}
IMHO , Employee class should be a simple POJO , in order to use it in other components , and you should create an AccountOperation Service (an EJB in Java EE context)
public class AccountOperation
{
Customer customer;
Employee employee;
public void createAnAccount(){
}
public void deleteAnAccount(){
}
public void debitAnAccount(){
}
}
For creating and deleting an account - create an instance of the account, and then pass the "whodunnit" as the employee - or some related identifier when something is done:
Account Account = new Account(Customer, AccountNumber);
Account.createAccount(Employee).
Account.deleteAccount(Employee).
For transactions you need two accounts - the credit and debit account. Because a transaction spans multiple accounts, the following method needs to be in it's own class:
public void AccountTransaction(Account CreditAccount,
Account DebitAccount,
float TransactionAmount.
Employee Employee){
CreditAccount.creditAccount(TransactionAmount, Employee);
DebitAccount.debitAccount(TransactionAmount, Employee);
}
most likely this method would be called by a number of "transaction types" (loan, interest payment, money transfer, etc.)
I have a WCF/REST web service that I'm considering using Linq to SQL to return database info from.
It's easy enough to do basic queries against tables and return rows, for example:
[WebGet(UriTemplate = "")]
public List<User> GetUsers()
{
List<User> ret = new List<User>(); ;
using (MyDataContext context = new MyDataContext())
{
var userResults = from u in context.Users select u;
ret = userResults.ToList<User>();
}
return ret;
}
But what if I want to return data from multiple tables or that doesn't exactly match the schema of the table? I can't figure out how to return the results from this query, for example:
var userResults = from u in context.Users
select new { u.userID, u.userName, u.userType,
u.Person.personFirstname, u.Person.personLastname };
Obviously the resulting rowset doesn't adhere to the "User" schema, so I can't just convert to a list of User objects.
I tried making a new entity in my object model that related to the result set, but it doesn't want to do the conversion.
What am I missing?
Edit: related question: what about results returned from stored procedures? Same issue, what's the best way to package them up for returning via the service?
Generally speaking, you shouldn't return domain objects from a service because if you do you'll run into issues like those you're finding. Domain objects are intended to describe a particular entity in the problem domain, and will often not fit nicely with providing a particular set of data to return from a service call.
You're best off decoupling your domain entities from the service by creating data transfer objects to represent them which contain only the information you need to transfer. The DTOs would have constructors which take domain object(s) and copy whatever property values are needed (you'll also need a parameterless constructor so they can be serialized), or you can use an object-object mapper like AutoMapper. They'll also have service-specific features like IExtensibleDataObject and DataMemberAttributes which aren't appropriate for domain objects. This frees your domain objects to vary independently of objects you send from the service.
You can create a Complex Type and instead of returning Anonymous object you return the Complex Type. When you map stored procedures using function import, you have a option to automatically create a complex type.
Create a custom class with the properties that you need:
public class MyTimesheet
{
public int Id { get; set; }
public string Data { get; set; }
}
Then create it from your Linq query:
using (linkDataContext link = new linkDataContext())
{
var data = (from t in link.TimesheetDetails
select new MyTimesheet
{
Id = t.Id,
Data = t.EmployeeId.ToString()
}).ToList();
}
Say I have a common pattern with a Customer object and a SalesOrder object. I have corresponding SalesOrderContract and CustomerContract objects that are similar, flatter objects used to serialize through a web service
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public Address ShippingAddress { get; set; }
//more fields...
}
public class Order
{
public int OrderId { get; set; }
public Customer Customer { get; set;
// etc
}
And my sales order contract looks like this
public class OrderContract
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
}
public class OrderTranslator
{
public static Order ToOrder(OrderContract contract)
{
return new Order { OrderId = contract.OrderId };
// just translate customer id or populate entire Customer object
}
}
I have a layer inbetween the service layer and business object layer that translates between the two. My question is this...do I populate the Order.Customer object on the other end since the Order table just needs the customer id. I don't carry the entire customer object in the OrderContract because it's not necessary and too heavy. But, as part of saving it, I have to validate that it's indeed a valid customer. I can do a few things
Populate the Order.Customer object completely based on the CustomerId when I translate between contract and entity.. This would require calling the CustomerRepository in a helper class that translates between entities and contracts. Doesn't feel right to me. Translator should really just be data mapping.
Create a domain service for each group of operations that performs the validation needed without populating the Order.Customer. This service would pull the Customer object based on Order.CustomerId and check to see if it's valid. Not sure on this because a sales order should be able to validate itself, but it's also not explicitly dealing with Orders as it also deals with Customers so maybe a domain service?
Create a seperate property Order.CustomerId and lazy load the customer object based on this.
Populate Order.Customer in from a factory class. Right now my factory classes are just for loading from database. I'm not really loading from datacontracts, but maybe it makes sense?
So the question is two part...if you have association properties in your enties that will be required to tell if something is completely valid before saving, do you just populate them? If you do, where you do actually do that because the contract/entity translator feels wrong?
The bottom line is that I need to be able to do something like
if (order.Customer == null || !order.Customer.IsActive)
{
//do something
}
The question is where does it make sense to do this? In reality my Order object has a lot of child entities required for validation and I don't want things to become bloated. This is why I'm considering making domain services to encapsulate validation since it's such a huge operation in my particular case (several hundred weird rules). But I also don't want to remove all logic making my objects just properties. Finding the balance is tough.
Hope that makes sense. If more background is required, let me know.
You have a couple of things going on here. I think part of the issue is mainly how you appear to have arranged your Translator class. Remember, for an entity, the whole concept is based on instance identity. So a Translator for an entity should not return a new object, it should return the correct instance of the object. That typically means you have to supply it with that instance in the first place.
It is perhaps useful to think in terms of updates vs creating a new object.
For an update the way I would structure this operation is as follows: I would have the web service that the application calls to get and return the contract objects. This web service calls both repositories and Translators to do it's work. The validation stays on the domain object.
In code an update would look something like the following.
Web Service:
[WebService]
public class OrderService
{
[WebMethod]
public void UpdateOrder(OrderContract orderContract)
{
OrderRepository orderRepository = new OrderRepository(_session);
// The key point here is we get the actual order itself
// and so Customer and all other objects are already either populated
// or available for lazy loading.
Order order = orderRepository.GetOrderByOrderContract(orderContract);
// The translator uses the OrderContract to update attribute fields on
// the actual Order instance we need.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the specific order instance with any properties updated
// so we can validate and then persist.
if (order.Validate())
{
orderRepository.Update(order);
}
else
{
// Whatever
}
}
}
Translator:
public static class OrderTranslator
{
public static void OrderContractToOrder(ref Order order, OrderContract orderContract)
{
// Here we update properties on the actual order instance passed in
// instead of creating a new Order instance.
order.SetSomeProperty(orderContract.SomeProperty);
// ... etc.
}
}
The key concept here is because we have an entity, we are getting the actual Order, the instance of the entity, and then using the translator to update attributes instead of creating a new Order instance. Because we are getting the original Order, not creating a new instance, presumably we can have all the associations either populated or populated by lazy load. We do not have to recreate any associations from an OrderContract so the issue goes away.
I think the other part of the issue may be your understanding of how a factory is designed. It is true that for entities a Factory may not set all the possible attributes - the method could become hopelessly complex if it did.
But what a factory is supposed to do is create all the associations for a new object so that the new object returned is in a valid state in terms of being a full and valid aggregate. Then the caller can set all the other various and sundry "simple" attributes.
Anytime you have a Factory you have to make decisions about what parameters to pass in. Maybe in this case the web service gets the actual Customer and passes it to the factory as a parameter. Or Maybe the web service passes in an Id and the factory is responsible for getting the actual Customer instance. It will vary by specific situation but in any case, however it gets the other objects required, a factory should return at minimum a fully populated object in terms of it's graph, i.e all relationships should be present and traversible.
In code a possible example of new Order creation might be:
[WebService]
public class OrderService
{
[WebMethod]
public void SaveNewOrder(OrderContract orderContract)
{
// Lets assume in this case our Factory has a list of all Customers
// so given an Id it can create the association.
Order order = OrderFactory.CreateNewOrder(orderContract.CustomerId);
// Once again we get the actual order itself, albeit it is new,
// and so Customer and all other objects are already either populated
// by the factory create method and/or are available for lazy loading.
// We can now use the same translator to update all simple attribute fields on
// the new Order instance.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the new order instance with all properties populated
// so we can validate and then persist.
if (order.Validate())
{
//Maybe you use a Repository - I use a unit of work but the concept is the same.
orderRepository.Save(order);
}
else
{
//Whatever
}
}
}
So, hope that helps?
So I've been learning about the Repository model, and it seems that it is expected that Repositories do not do a lot of intricate logic. However I also read that most of the business logic should not be inside of my Controllers. So where do I put it?
I've looked at some sample applications and it seems that they have another layer called Services that do more intricate logic for things. So how does this factor into the MVC pattern?
Do I want to build my services to access my repositories, and then my controllers to access my services? Like this?
interface IMembershipService
{
bool ValidateUser(string username, string password);
MembershipCreateStatus Create(string username, string password);
}
interface IMembershipRepository
{
MembershipCreateStatus Create(string username, string password);
}
class MembershipRepository : IMembershipRepository
{
public MembershipRepository(ISession session)
{
**// this is where I am confused...**
}
}
class MembershipService : IMembershipService
{
private readonly IMembershipRepository membershipRepository;
public MembershipService(IMembershipRepository membershipRepository)
{
this.membershipRepository = membershipRepository;
}
public bool ValidateUser(string username, string password)
{
// validation logic
}
public MembershipCreateStatus Create(string username, string password)
{
return membershipRepository.Create(username, password);
}
}
class MembershipController : Controller
{
private readonly IMembershipService membershipService;
public MembershipController(IMembershipService membershipService)
{
this.membershipService = membershipService
}
}
The marked part of my code is what confuses me. Everything I have read said I should be injecting my ISession into my repositories. This means I could not be injecting ISession into my services, so then how do I do Database access from my Services? I'm not understanding what the appropriate process is here.
When I put ValidateUser in my IMembershipRepository, I was told that was 'bad'. But the IMembershipRepository is where the database access resides. That's the intention, right? To keep the database access very minimal? But if I can't put other logic in them, then what is the point?
Can someone shed some light on this, and show me an example that might be more viable?
I am using Fluent nHibernate, ASP.NET MVC 3.0, and Castle.Windsor.
Should I instead do something like ...
class MembershipService
{
private readonly IMembershipRepository membershipRepository;
public MembershipService(ISession session)
{
membershipRepository = new MembershipRepository(session);
}
}
And never give my Controllers direct access to the Repositories?
Everything I have read said I should be injecting my ISession into my repositories.
That's correct. You need to inject the session into the repository constructor because this is where the data access is made.
This means I could not be injecting ISession into my services, so then how do I do Database access from my Services?
You don't do database access in your services. The service relies on one or more repositories injected into its constructor and uses their respective methods. The service never directly queries the database.
So to recap:
The repository contains the simple CRUD operations on your model. This is where the data access is performed. This data access doesn't necessary mean database. It will depend on the underlying storage you are using. For example you could be calling some remote services on the cloud to perform the data access.
The service relies on one or more repositories to implement a business operation. This business operation might depend on one or more CRUD operations on the repositories. A service shouldn't even know about the existence of a database.
The controller uses the service to invoke the business operation.
In order to decrease the coupling between the different layers, interfaces are used to abstract the operations.
interface IMembershipService
{
bool ValidateUser(string username, string password);
MembershipCreateStatus Create(string username, string password);
}
Creating a service like this an anti-pattern.
How many responsibilities does a service like this have? How many reasons could it have to change?
Also, if you put your logic into services, you are going to end up with an anemic domain. What you will end up with is procedural code in a Transaction Script style. And I am not saying this is necessarily bad.
Perhaps a rich domain model is not appropriate for you, but it should be a conscious decision between the two, and this multiple responsibility service is not appropriate in either case.
This should be a HUGE red flag:
public MembershipCreateStatus Create(string username, string password)
{
return membershipRepository.Create(username, password);
}
What is the point? Layers for the sake of layers? The Service adds no value here, serves no purpose.
There are a lot of concepts missing.
First, consider using a Factory for creating objects:
public interface IMembershipFactory {
MembershipCreateStatus Create(string username, string password);
}
The factory can encapsulate any logic that goes into building an instance or beginning the lifetime of an entity object.
Second, Repositories are an abstraction of a collection of objects. Once you've used a factory to create an object, add it to the collection of objects.
var result = _membershipFactory.Create("user", "pw");
if (result.Failed); // do stuff
_membershipRepository.Add(status.NewMembership); // assumes your status includes the newly created object
Lastly, MyEntityService class that contains a method for every operation that can be performed on an Entity just seems terribly offensive to my senses.
Instead, I try to be more explicit and better capture intent by modeling each operation not as a method on a single Service class, but as individual Command classes.
public class ChangePasswordCommand {
public Guid MembershipId { get; set; }
public string CurrentPassword { get; set; }
public string NewPassword { get; set; }
}
Then, something has to actually do something when this command is sent, so we use handlers:
public interface IHandle<TMessageType> {
void Execute(TMessageType message);
}
public class ChangePasswordCommandHandler : IHandle<ChangePasswordCommand> {
public ChangePasswordCommandHandler(
IMembershipRepository repo
)
{}
public void Execute(ChangePasswordCommand command) {
var membership = repo.Get(command.MembershipId);
membership.ChangePassword(command.NewPassword);
}
}
Commands are dispatched using a simple class that interfaces with our IoC container.
This helps avoids monolithic service classes and makes a project's structure and location of logic much clearer.