Laravel Repositories inside other repositories - laravel

So I have recently started utilizing the Repository pattern in my work projects. I keep running into the same question that I cannot seem to find an answer to:
Is it OK to inject another repository into an existing repository? What are the negative effects of doing so?
For instance:
class CrawlsRepository implements CrawlsRepositoryInterface {
public function __construct(ArchiveRepository $archive)
{
$this->archive = $archive;
}
...
...
public function getCrawlList()
{
// Do stuff with $this->crawl
// Do stuff with $this->archive
}
}
There are certain methods inside the CrawlsRepository that just have to use the Archive Model, meaning it needs to use the ArchiveRepository to maintain the pattern.
What do you guys/gals do in these situations? I feel like I'm missing something here, I have read before, people saying that if you feel the need to pull another repository in, then evaluate weather you really need 2 separate Repositories in the first place, let me preemptively answer that, I do.
Thanks for any direction you can provide! :)

Technically it is ok to do so. In fact it's good because you are using dependency injection, so you arn't tied to only one implementation.
Conceptually, repository represents wrappers around data source access. So I think it's okay to use another repository to abstract data retrieving further.
On the other hand when you say:
There are certain methods inside the CrawlsRepository that just have to use the Archive Mode then these methods have NOTHING to do inside the CrawlsRepository. They belong to the ArchiveRepository.
The use case here is when you want to return something that belongs to your CrawlRepository, but you want to return Archives that are linked in some way to your data.
In this case, the CrawlRepository HAVE TO call the ArchiveRepository to gather the needed archives before returning.
But again, if a method only need the ArchiveRepository, then it seem you are doing it wrong.
I hope my explanation is clear enough because it's quite an abstract and subjective topic.

Related

official way to implement repository pattern into laravel

I want to know if it is good to use repository pattern in laravel or not. I read in somewhere that it's a DRY to use repository pattern because We use Eloquent in laravel and some other places like here
https://www.dunebook.com/brief-overview-of-design-patterns-used-in-laravel/3
so here is example of the above link :
interface UserRepository {
public function all();
}
and the repo
use User;
class EloquentUserRepository implements UserRepository {
public function all()
{
return User::all();
}
and finally in controller :
User::find($id)
gives advice to use repository pattern and as I feel it's a kind of duplication in code . any help or source to get hint from?
The repository pattern is doing something like:
Hey interface! Give me all users (UsersRepository all)
Hey Eloquent! Give me all users. (EloquentUsersRepository)
The part when you call for User::find($id) in your controller (I'm assuming is a mistake, since you wrote an all function on your repository is that what you should be using on your controller).
I've done some implementations of the repository pattern on Laravel and I've done it that way. The only thing you did not mention, but I guess you are doing as well is binding the interface to the EloquentUserRepository implementation using the Laravel ioc container, so everytime you ask for an instance of the interface it gets automatically resolved with an eloquent implementation instance.
It actually seems that you are repeating code but you are not, sometimes the repository pattern may not be suitable to your needs today so it seems you are just adding unnecesary complexity to the code. In our case we started writing an application using the repository pattern but didn't take advantage of it so we were just writing that unnecessary layer of complexity, when we realised we got rid of it and decided to use the models directly, some time after we started to need it again under certain circumstances so we implemented it again, as I said, it all depends on your needs at the time.
The most mentioned need for using this pattern is the possibility of changing of ORM easily, but in our case that never happened and honestly, doesn't seem to be happening. But one useful use case for having a repository would be the following: Let's suppose you an algorithm that for example, calculates the number of users having a username starting with the letter a, ideally you would not implement this on your framework project, but on a separate one, that way you can test it independently and reuse it. In short words, to count the usernames that start with a you don't actually need to know that your project is a Laravel one, a Codeigniter one, has Eloquent, Redis, or the users written in an Excel document, all you need to know is that it can provide you with all users, and that's why having a users repository interface is useful, your algorithm would just say I need all users and would not care about anything else.

How to solve the problem of too many methods in the command processor in command pattern

We plan to apply the command pattern in our process management project: there are
a Command interface to implement
a CommandProcessor, which truly execute some task
The CommandProcessor is passed to the Command instance through constructor so that the execute() method in Command will eventually trigger the true execution in CommandProcessor
So the code of CommandProcessor looks like this:
public class CommandProcessor {
public doWork1() {
//implementation
}
public doWork2() {
//implementation
}
public doWork3() {
//implementation
}
...
public doWork200() {
//implementation
}
}
As the code snippet indicates, the downside of command pattern in our use case is there might be hundreds of commands and thus the CommandProcessor might be difficult to maintain in the long term. So how to resolve this drawback?
This does not feel like the command pattern to me. the design you have highlighted does not hide the implementation detail from the caller. It puts all the logic for which method to call with the caller rather than it being hidden behind an interface.
The main reason for the Command pattern is the caller of the command does not need to know anything at all about what the command is, what it does, all of that is encapsulated in the command itself.
I feel your fears about having 200 command methods have merit. Firstly consider what happens when you add, remove or change the signiture of any of these work methods. Not only do you need to change the interface but also all the concrete classes that implement that interface, and all the locations where the interface is called.
Typically the command pattern has one execute interface, see this wikipedia article for a description of the command_pattern
As #robert mentioned in your comments i think you should rethink your API.
Edit
After a good conversation with #Rui I better understand the question and have the following to say.
Whilst I misunderstood the original question I'm still prepared to stand by the statement that a redesign is needed. Whilst the command pattern is being followed I dont think the spirit of the pattern is. The object passed to the commands (the commandProcessor) is the receiver of the commands actions, but this does not look like a proper object. Obviously I lack context but for me any object that ends in -er raises big flags as not really being an object, but more a collection of methods that act on someone elses data.
Here is a good little write up with some links. I often find that classes like managers, processors or helpers go hand in hand with an Anemic Domain Model. Maybe you are on the beginnings of the right track and i would challange you to look at that commandProcessor and see if its not actually a number of descrete objects that can encapsulate their own data and methods.

Single responsibility principle - function

I'm reading some tuts about SOLID programming, and I'm trying to refactor my test project to implement some of those rules.
Often I have doubts with SingleResponsibilityPrinciple, so I hope someone could help me with that.
As I understood, SRP means that (in case of a function), function should be responsible for only one thing. And that's seems pretty easy and simple, but I do get in a trap of doing more than thing.
This is simplified example:
class TicketService {
private ticket;
getTicket() {
httpClient.get().then(function(response) {
ticket = response.ticket;
emit(ticket); <----------------------
});
}
}
The confusing part is emit(ticket). So, my function is named getTicket, that's exactly what I'm doing there (fetching it from server e.g.), but on the other hand, I need to emit that change to all other parts of my application, and let them know that ticket is changed.
I could create separate set() function, where I could do setting of private variable, and emit it there, but that seems like a same thing.
Is this wrong? Does it break the rule? How would you fix it?
You could also return the ticket from the getTicket() function, and then have a separate function called setUpdatedTicket() that takes a ticket and sets the private parameter, and at the end calls the emit function.
This can lead to unexpected behavior. If I want to re-use your class in the future and I see with auto-completion in my IDE the method getTicket() I expect to get a Ticket.
However renaming this method to mailChangedTicket, ideally you want this method to call the getTicket method (which actually returns the ticket) and this way you have re-usable code which will make more sense.
You can take SRP really far, for example your TicketService has a httpClient, but it probably doesn't matter where the ticket comes from. In order to 'fix' this, you will have to create a seperate interface and class for this.
A few advantages:
Code is becoming more re-usable
It is easier to test parts separately
I can recommend the book 'Clean Code' from Robert C. Martin which gives some good guidelines to achieve this.

Is it common practice to hold a repository globally? [closed]

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!

How to avoid injecting dependencies into an object so that it can pass them on?

I am interested in applying dependency injection to my current project, which makes use of the MVC pattern.
My controllers will call the models and therefore will need to inject the dependencies into the models. To do this, the controller must have the dependencies (such as a database object) in the first place. The controller doesn't need to make use of some of these dependencies (such as the database object), so I feel that it shouldn't be given this dependency. However, it has to have these dependencies if it is to inject them into the model objects.
How can I avoid having dependencies injected into an object just so that it can pass them on? Doing so feels wrong and can result in many dependencies being injected into an object.
Edit: I am using PHP.
I agree with your concerns. It's a code smell to take dependencies for the sole purpose of passing them on to other dependencies.
Depending on the exact interaction between those dependencies, you have a couple of options:
If only one instance of the dependency is needed
If your Controller only needs a single instance of a dependency, then just take a dependency on that instead.
(apologies for the c# code)
Don't do this:
public class MyController
{
public MyController(IDb db)
{
var dep = new MyDependency(db);
// Use dep or save it for later
}
}
Instead, you can do this:
public class MyController
{
public MyController(MyDependency dep)
{
// Use dep or save it for later
}
}
You may want to consider MyDependency behind an interface itself. See also Refactoring to Aggregate Services.
If you need to create multiple instances during the Controller's lifetime
Sometimes, however, you need to create multiple instances dynamically. This is often the case when you need a value that's only available at run-time before you can fully populate a dependency.
In this case, an Abstract Factory is an excellent and universal solution.
I'm not speaking from PHP experience but you should look into Inversion of Control (IOC) Containers.
This question on StackOverflow talks about IOC Containers for PHP. For a quick overview of some of the other benefits of IOC Containers you should check this question, probably one of my favourite on the site. Check the last answer ;)
How can I avoid having dependencies
injected into an object just so that
it can pass them on? Doing so feels
wrong and can result in many
dependencies being injected into an
object.
Most people don't realise that an IOC container makes the need to store temporary dependencies void. This in turn makes your code cleaner and easier to follow. Each class (or module) of your code simply asks for what it needs. IOC Containers can manage object life time, so even if two classes ask for the same dependency independently, they can receive the same instance, which is pretty neat.

Resources