Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I see two main "schools of thoughts" when it comes to creating larger-scale enterprise-wide apps on .NET (Winforms, WPF, ASP.NET).
Some folks use the "repository pattern" which uses a repository that knows how to fetch, insert, update and delete objects. Those objects are rather "dumb" in that they don't necessarily contain a whole lot of logic - e.g. they're more or less data-transfer objects.
The other camp uses what I call "smart" business objects that know how to load themselves, and they typically have a Save(), possibly Update() or even Delete() method. Here you really don't need any repository - the objects themselves know how to load and save themselves.
Big question is: which do you use or prefer? And why?
Do you use the same approach in all your apps, or do you have any particular criteria when to choose one approach over the other? If so - what are those criteria?
I'm not trying to start a flame-war here - just trying to find out what everyone thinks about this and what your opinion is, and why you use one (or both) patterns over the other.
Thanks for any constructive input!
I use the repository pattern because of the Single Responsibility Principle. I don't want each individual object to have to know how to save, update, delete itself, when this can be handled by one single generic repository
The repository pattern doesn't necessary lead to dumb objects.
If the objects have no logic outside Save/Update, you're probably doing too much outside the object.
Idealy, you should never use properties to get data from your object, compute things, and put data back in the object. This is a break of encapsulation.
So the objects should not be anemic except if you use simple DTO objects with CRUD operations.
Then separating the persistence concerns from your object concerns is a good way to have Single Responsibility.
Here are two interesting articles I came across
Repository-is-the-new-singleton
The DAL should go all the way to UI
I think the most important side-effect of using the Repository pattern vs. the ActiveRecord pattern is testing and extensibility.
Without having your ActiveRecord object contain a repository itself how would you isolate data retrieval in your test cases? You can't really fake or mock it easily.
Besides testing it would also be much more difficult to swap out data access technologies, for example from Linq-to-SQL to NHibernate or EntityFramework (though this doesn't happen often admittedly).
It really depends on the needs of the application, but when dealing with a complex business model, I prefer ActiveRecord. I can encapsulate (and test) the business logic all in one place.
Most ORM's (EF, nHibernate, etc...) serve as your Repository. Many people consider a layer on top of an ORM that encapsulates all data interaction as a Repository, which I believe to be incorrect. According to Martin Fowler, a Repository encapsulates data access as a collection. So having individual methods for all data retrieval/mutation might be using a Data Mapper or a Data Access Object.
Using ActiveRecord, I like to have an "Entity" base class. I typically use an ORM (repository) with this base class, so all of my entities have a GetById, AsQueryable, Save and Delete methods.
If I'm using more of a Service Oriented Architecture, I'll use a repository (one that masks direct data access or an ORM) and call it directly in my services.
Related
In our new project we decided to use hexagonal architecture. We decided to use repository pattern to gain more data access abstraction. We are using command bus pattern as service layer.
In our dashboard page we need a lot of data and because of that we should use 3 level many to many relations (user -> projects -> skills -> review) and also skills should be active(status=1).
The problem rises here, where should i put this?
$userRepository->getDashboardData($userId).
2.$userRepository->getUser($userId)->withProjects()->withActiveSkills()->withReviews();
3.$user = $userRepository->getById();
$projects = $projectRepository->getByUserId($user->id);
$skills = $skillRepository->getActiveSkillsByProjectsIds($projectIds);
In this case, I couldn't find the benefits of repository pattern except coding to interface which can be achived with model interfac.
I think solution 3 is prefect but it adds a lot of work.
You have to decide (for example) from an object-oriented perspective if a "User" returned is one that has a collection of skills within it. If so, your returned user will already have those objects.
In the case of using regular objects, try to avoid child entities unless it makes good sense. Like, for example.. The 'User' entity is responsible for ensuring that the child entities play by the business rules. Prefer to use a different repository to select the other types of entities based on whatever other criteria.
Talking about a "relationship" in this way makes me feel like you're using ActiveRecord because otherwise they'd just be child objects. The "relationship" exists in the relational database. It only creeps into your objects if you're mixing database record / object like with AR.
In the case of using ActiveRecord objects, you might consider having specific methods on the repository to load the correctly configured member objects. $members->allIncludingSkills() or something perhaps. This is because you have to solve for N+1 when returning multiple entities. Then, you need to use eager-loading for the result set and you don't want to use the same eager loading configuration for every request.. Therefore, you need a way to delineate configurations per request.. One way to do this is to call different methods on the repository for different requests.
However, for me.. I'd prefer not to have a bunch of objects with just.. infinite reach.. For example.. You can have a $member->posts[0]->author->posts[0]->author->posts[0]->author->posts[0].
I prefer to keep things as 'flat' as possible.
$member = $members->withId($id);
$posts = $posts->writtenBy($member->id);
Or something like that. (just typing off the top of my head).
Nobody likes tons of nested arrays and ActiveRecord can be abused to the point where its objects are essentially arrays with methods and the potential for infinite nesting. So, while it can be a convenient way to work with data. I would work to prevent abusing relationships as a concept and keep your structures as flat as possible.
It's not only very possible to code without ORM 'relationship' functionality.. It's often easier.. You can tell that this functionality adds a ton of trouble because of just how many features the ORM has to provide in order to try to mitigate the pain.
And really, what's the point? It just keeps you from having to use the ID of a specific Member to do the lookup? Maybe it's easier to loop over a ton of different things I guess?
Repositories are really only particularly useful in the ActiveRecord case if you want to be able to test your code in isolation. Otherwise, you can create scopes and whatnot using Laravel's built-in functionality to prevent the need for redundant (and consequently brittle) query logic everywhere.
It's also perfectly reasonable to create models that exist SPECIFICALLY for the UI. You can have more than one ActiveRecord model that uses the same database table, for example, that you use just for a specific user-interface use-case. Dashboard for example. If you have a new use-case.. You just create a new model.
This, to me.. Is core to designing systems. Asking ourselves.. Ok, when we have a new use-case what will we have to do? If the answer is, sure our architecture is such that we just do this and this and we don't really have to mess with the rest.. then great! Otherwise, the answer is probably more like.. I have no idea.. I guess modify everything and hope it works.
There's many ways to approach this stuff. But, I would propose to avoid using a lot of complex tooling in exchange for simpler approaches / solutions. Repository is a great way to abstract away data persistence to allow for testing in isolation. If you want to test in isolation, use it. But, I'm not sure that I'm sold much on how ORM relationships work with an object model.
For example, do we have some massive Member object that contains the following?
All comments ever left by that member
All skills the member has
All recommendations that the member has made
All friend invites the member has sent
All friends that the member has established
I don't like the idea of these massive objects that are designed to just be containers for absolutely everything. I prefer to break objects into bits that are specifically designed for use-cases.
But, I'm rambling. In short..
Don't abuse ORM relationship functionality.
It's better to have multiple small objects that are specifically designed for a use-case than a few large ones that do everything.
Just my 2 cents.
I'm working with Laravel 5 but I think this question can be applied beyond the scope of a single framework or language. The last few days I've been all about writting interfaces and implementations for repositories, and then binding services to the IoC and all that stuff. It feels extremely slow.
If I need a new method in my service, say, Store::getReviews() I must create the relationship in my entity model class (data source, in this case Eloquent) then I must declare the method in the repo interface to make it required for any other implementation, then I must write the actual method in the repo implementation, then I have to create another method on the service that calls on the repo to extract all reviews for the store... (intentional run-on sentence) It feels like too much.
Creating a new model now isn't as simple as extending a base model class anymore. There are so many files I have to write and keep track of. Sometimes I'll get confused as of to where exactly I should put something, or find halfway throught setting up a method that I'm in the wrong class. I also lost Eloquent's query building in the service. Everytime I need something that Eloquent has, I have to implement it in the repo and the service.
The idea behind this architecture is awesome but the actual implementation I am finding extremely tedious. Is there a better, faster way to do things? I feel I'm beeing too messy, even though I put common methods and stuff in abstract classes. There's just too much to write.
I've wrestled with all this stuff as I moved to Laravel 5. That's when I decided to change my approach (it was tough decision). During this process I've come to the following conclusions:
I've decided to drop Eloquent (and the Active Record pattern). I don't even use the query builder. I do use the DB fascade still, as it's handy for things like parameterized query binding, transactions, logging, etc. Developers should know SQL, and if they are required to know it, then why force another layer of abstraction on them (a layer that cannot replace SQL fully or efficiently). And remember, the bridge from the OOP world to the Relational Database world is never going to be pretty. Bear with me, keeping reading...
Because of #1, I switched to Lumen where Eloquent is turned off by default. It's fast, lean, and still does everything I needed and loved in Laravel.
Each query fits in one of two categories (I suppose this is a form of CQRS):
3.1. Repositories (commands): These deal with changing state (writes) and situations where you need to hydrate an object and apply some rules before changing state (sometimes you have to do some reads to make a write) (also sometimes you do bulk writes and hydration may not be efficient, so just create repository methods that do this too). So I have a folder called "Domain" (for Domain Driven Design) and inside are more folders each representing how I think of my business domain. With each entity I have a paired repository. An entity here is a class that is like what others may call a "model", it holds properties and has methods that help me keep the properties valid or do work on them that will be eventually persisted in the repository. The repository is a class with a bunch of methods that represent all the types of querying I need to do that relates to that entity (ie. $repo->save()). The methods may accept a few parameters (to allow for a bit of dynamic query action inside, but not too much) and inside you'll find the raw queries and some code to hydrate the entities. You'll find that repositories typically accept and/or return entities.
3.2. Queries (a.k.a. screens?): I have a folder called "Queries" where I have different classes of methods that inside have raw queries to perform display work. The classes kind of just help for grouping together things but aren't the same as Repositories (ie. they don't do hydrating, writes, return entities, etc.). The goal is to use these for reads and most display purposes.
Don't interface so unnecessarily. Interfaces are good for polymorphic situations where you need them. Situations where you know you will be switching between multiple implementations. They are unneeded extra work when you are working 1:1. Plus, it's easy to take a class and turn it into an interface later. You never want to over optimize prematurely.
Because of #4, you don't need lots of service providers. I think it would be overkill to have a service provider for all my repositories.
If the almost mythological time comes when you want to switch out database engines, then all you have to do is go to two places. The two places mentioned in #3 above. You replace the raw queries inside. This is good, since you have a list of all the persistence methods your app needs. You can tailor each raw query inside those methods to work with the new data-store in the unique way that data-store calls for. The method stays the same but the internal querying gets changed. It is important to remember that the work needed to change out a database will obviously grow as your app grows but the complexity in your app has to go somewhere. Each raw query represents complexity. But you've encapsulated these raw queries, so you've done the best to shield the rest of your app!
I'm successfully using this approach inspired by DDD concepts. Once you are utilizing the repository approach then there is little need to use Eloquent IMHO. And I find I'm not writing extra stuff (as you mention in your question), all while still keeping my app flexible for future changes. Here is another approach from a fellow Artisan (although I don't necessarily agree with using Doctrine ORM). Good Luck and Happy Coding!
Laravel's Eloquent is an Active Record, this technology demands a lot of processing. Domain entities are understood as plain objects, for that purpose try to utilizes Doctrime ORM. I built a facilitator for use Lumen and doctrine ORM follow the link.
https://github.com/davists/Lumen-Doctrine-DDD-Generator
*for acurated perfomance analisys there is cachegrind.
http://kcachegrind.sourceforge.net/html/Home.html
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am working on a web application in spring following the MVC pattern and was wondering what is considered "best practice" for making a solid service layer. The reason for this question is the following example situation:
A page for editing user information is loaded. After this form is submitted I gather all of its data in my controller method in a specific Command class containing only the data needed for the action that follows (updating the user).
I can think of several situations now to pass this information to my service layer:
Passing the command itself: userService.save(command);
Passing a model class, fetched in the controller: userService.save(user);
Passing both a model class and the command: userService.save(user, command);
Passing all of the parameters individually: userService.save(command.getName(), ...)
In my opinion passing the command class itself looks like the most elegant solution as I can first validate all the values automatically using the framework then pass them to my service. My concern here is that when I call the method from another class (not through my form / controller) I can fill this command object with invalid data, resulting in possible errors in the service layer.
What would you recommend and why?
After seeing your I have the following ideas
Passing the command itself: userService.save(command);
This may not be a goode idea since your Service layer is unnecessarily
dependent on Command object
Passing a model class, fetched in the controller: userService.save(user);
I will vote for this. Service layer only what it really supposed to
know
Passing both a model class and the command: userService.save(user, command);
No. Same as the first option
Passing all of the parameters individually: userService.save(command.getName(), ...)
Hmmmm... not sure.. May be a mainitenance overhead in future.
I think if you want to do the validation, Use validation util classes to do the validation
which can be used for both Service and UI layer. Here a lot validation can be centralized.
In his MVC book, Dino Esposito recommends creating a 'worker' class that takes and returns a viewmodel. The controller calls the worker with the viewmodel and then the worker delegates as necessary. I've not used it in practise but in theory it appears to be a nice solution.
Any option using your Command object will cause trouble. It breaks loose coupling. Now your service layer is tightly coupled with service layer. Please don't do it.
(EDIT: In my answer below, when I say Model for presentation layer I am talking about View Model and for service layer it is the Domain Model)
Sending your Model object looks like a good option. But, it depends on how the model was created. Some times, presentation layer will need a different model structure and the service layer will need a moderatley/completely different structure.
If both layers have different needs, then you need to create 2 model structure. This way service layer's model structure doesn't have to change when presentation layer changed. This is important as the service may have multiple consumers and may not be able to change when presentation layer changes.
If they don't have different structure, I would still create them from service layer point of view as service is the real reusable component here.
A good pattern to follow when dealing with commands in multi-layered systems is to have a CommandBus service that routes your commands to their specific handlers. That way, you decouple your controller from your services (while coupling it with a generic routing system).
commandBus.handle(command);
You must do additional work in configuring the command bus handlers, but it will pay in the long term when you'll be able to reuse that routing information:
commandBus.register(commandType, handlerService);
and you may then be able to move the validation of the commands in the commandBus service (even though this will mean some mixing of concerns for the commandBus)
commandBus.registerValidator(commandType, validatorsCollection);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In repository examples, I see the repository instantiated when the Session opens, which seems as if it is around for the entire Session. In controller actions, the data layer is then accessed through calls to the repository. Is this common practice? Wouldn't it make more sense to be instantiating the repository in an on need basis per action request?
Edit: A more exact scenario.
public class myController : Controller {
IMyRepository myRepository;
public myController(IMyRepository repositoryParam){
myRepository = repositoryParam;
}
public ActionResult someAction(){
MyClass myClass = myRepository.RepositoryAction();
}
}
In this scenario, myRepository is global to myController (note: this is based off an example from Steven Sanderson). I have seen it also defined for all controllers to access, but this is a simple, exact, example. In this example, why would the repository be used globally instead of on a per use basis?
To answer your question, Travis, you should read up a bit on the Repository Pattern. This pattern is used to provide a number of advantages, including:
It centralizes the data logic or Web service access logic.
It provides a substitution point for the unit tests.
It provides a flexible architecture that can be adapted as the overall design of the application evolves.
As to your question: "Is this a common practice?" the answer is, "It should be." but, unfortunately, I don't see it as much as I would prefer.
Now, in your example, you show the repository being created within the context of your controller class. (Please note that this is NOT the same thing as an object being made "global" as you put it. Global means that the object is accessible from any scope. Read more about it here at Wikipedia.)
In any case, one of the advantages is that the repository allows you to change between how you are accessing your data (or even where your data is being accessed) by using the correct, concrete version of the repository. So, you may have:
IRepository - Your interface which the concrete repositories implement.
DatabaseRepository - Accesses your data in a database.
FlatFileRepository - Access your data out of a flat file.
etc.
If you wish to switch to other data sources, it is a simple as swapping out the concrete implementation in your controller. (Please note, there are more advanced and flexible ways of doing this through dependency injection, but that is out of scope of this question, although it does/can play heavily in the repository pattern.)
In any case, say your project team decides "Hey, we're going to switch from storing all our data in flat files to using a database." Well, if you have scattered the instantiations of that specific repository throughout your code, you now have a lot of different areas to fix and update, somewhat negating the advantages of the repository pattern. However, by declaring a member repository of your controller, you just switch from a FlatFileRepository to a DatabaseRepository, implement the new repository, and you are finished! Everybody on the team is happy!
Update: "Why Instantiate a Class Variable?"
To answer that question, you have to think of your two options. The first option is that you could hold a relatively small object in memory. The other alternative is you could instantiate a new object in memory every time that a user needs to access one of your actions causing new memory to be allocated (and deallocated when you leave the scope that the object was in) and requiring more work by the server which is hosting your web app.
If you think about how a website is used, users are hitting those actions on a frequent basis. Every action signifies a portion of your website. If you instantiated every single time you needed the repository, you would quickly give the server a much bigger workload than it actually needs - particularly as your site grows in size. (I am sure other folks can think of other reasons why you would want to do it the way shown in the tutorial vs. instantiation in each individual action.)
And, then, of course, there is the refactoring issue as I mentioned above. That is about "efficiency of making changes" or improving the maintainability.
Hope that helps you a bit more and better answers your question!
A few general questions to those who are well-versed in developing web-based applications.
Question 1:
How do you avoid the problem of "dependency carrying"? From what I understand, the first point of object retrieval should happen in your controller's action method. From there, you can use a variety of models, classes, services, and components that can require certain objects.
How do you avoid the need to pass an object to another just because an object it uses requires it? I'd like to avoid going to the database/cache to get the data again, but I also don't want to create functions that require a ton of parameters. Should the controller action be the place where you create every object that you'll eventually need for the request?
Question 2:
What data do you store in the session? My understanding is that you should generally only store things like user id, email address, name, and access permissions.
What if you have data that needs to be analyzed for every request when a user is logged in? Should you store the entire user object in the cache versus the session?
Question 3:
Do you place your data-retrieval methods in the model itself or in a separate object that gets the data and returns a model? What are the advantages to this approach?
Question 4:
If your site is driven by a user id, how do you unit test your code base? Is this why you should have all of your data-retrieval methods in a centralized place so you can override it in your unit tests?
Question 5:
Generally speaking, do you unit test your controllers? I have heard many say that it's a difficult and even a bad practice. What is your opinion of it? What exactly do you test within your controllers?
Any other tidbits of information that you'd like to share regarding best practices are welcome! I'm always willing to learn more.
How do you avoid the problem of "dependency carrying"?
Good object oriented design of a BaseController SuperClass can handle a lot of the heavy lifting of instantiating commonly used objects etc. Usage of Composite types to share data across calls is a not so uncommon practice. E.g. creating some Context Object unique to your application within the Controller to share information among processes isn't a terrible idea.
What data do you store in the session?
As few things as is humanly possible.
If there is some data intensive operation which requires a lot of overhead to process AND it's required quite often by the application, it is a suitable candidate for session storage. And yes, storage of information such as User Id and other personalization information is not a bad practice for session state. Generally though the usage of cookies is the preferred method for personalization. Always remember though to never, ever, trust the content of cookies e.g. properly validate what's read before trusting it.
Do you place your data-retrieval methods in the model itself or in a separate object that gets the data and returns a model?
I prefer to use the Repository pattern for my models. The model itself usually contains simple business rule validations etc while the Repository hits a Business Object for results and transformations/manipulations. There are a lot of Patterns and ORM tools out in the market and this is a heavily debated topic so it sometimes just comes down to familiarity with tools etc...
What are the advantages to this approach?
The advantage I see with the Repository Pattern is the dumber your models are, the easier they are to modify. If they are representatives of a Business Object (such as a web service or data table), changes to those underlying objects is sufficiently abstracted from the presentation logic that is my MVC application. If I implement all the logic to load the model within the model itself, I am kind of violating a separation of concerns pattern. Again though, this is all very subjective.
If your site is driven by a user id, how do you unit test your code base?
It is highly advised to use Dependency Injection whenever possible in code. Some IoC Containers take care of this rather efficiently and once understood greatly improve your overall architecture and design. That being said, the user context itself should be implemented via some form of known interface that can then be "mocked" in your application. You can then, in your test harness, mock any user you wish and all dependent objects won't know the difference because they will be simply looking at an interface.
Generally speaking, do you unit test your controllers?
Absolutely. Since controllers are expected to return known content-types, with the proper testing tools we can use practices to mock the HttpContext information, call the Action Method and view the results to see they match our expectations. Sometimes this results in looking only for HTTP status codes when the result is some massive HTML document, but in the cases of a JSON response we can readily see that the action method is returning all scenario's information as expected
What exactly do you test within your controllers?
Any and all publicly declared members of your controller should be tested thoroughly.
Long question, longer answer. Hope this helps anyone and please just take this all as my own opinion. A lot of these questions are religious debates and you're always safe just practicing proper Object Oriented Design, SOLID, Interface Programming, DRY etc...
Regarding dependency explosion, the book Dependency Injection in .NET (which is excellent) explains that too many dependencies reveals that your controller is taking on too much responsibility, i.e. is violating the single responsibility principle. Some of that responsibility should be abstracted behind aggregates that perform multiple operations.
Basically, your controller should be dumb. If it needs that many dependencies to do its job, it's doing too much! It should just take user input (e.g. URLs, query strings, or POST data) and pass along that data, in the appropriate format, to your service layer.
Example, drawn from the book
We start with an OrderService with dependencies on OrderRepository, IMessageService, IBillingSystem, IInventoryManagement, and ILocationService. It's not a controller, but the same principle applies.
We notice that ILocationService and IInventoryManagement are both really implementation details of an order fulfillment algorithm (use the location service to find the closest warehouse, then manage its inventory). So we abstract them into IOrderFulfillment, and a concrete implementation LocationOrderFulfillment that uses IInventoryManagement and ILocationService. This is cool, because we have hidden some details away from our OrderService and furthermore brought to light an important domain concept: order fulfillment. We could implement this domain concept in a non-location-based way now, without having to change OrderService, since it only depends on the interface.
Next we notice that IMessageService, IBillingSystem, and our new IOrderFulfillment abstractions are all really used in the same way: they are notified about the order. So we create an INotificationService, and make MessageNotification a concrete implementation of both INotificationService and IMessageService. Similarly for BillingNotification and OrderFulfillmentNotification.
Now here's the trick: we create a new CompositeNotificationService, which derives from INotificationService and delegates to various "child" INotificationService instances. The concrete instance we use to solve our original problem will delegate in particular to MessageNotification, BillingNotification, and OrderFulfillmentNotification. But if we wish to notify more systems, we don' have to go edit our controller: we just have to implement our particular CompositeNotificationService differently.
Our OrderService now depends only on OrderRepository and INotificationService, which is much more reasonable! It has two constructor parameters instead of 5, and most importantly, it takes on almost no responsibility for figuring out what to do.