I have two panels, one for the admins and the other for partners. And there are two OrderController with Admin\OrderController and Partner\OrderController namespaces.

They both look very similar. What is the best way to avoid duplicate code in two controllers.

They have two parts, the first part in authorising and validating the input, and the second part is doing the logic like storing the order. the second part is the duplicate code. So what about using trait with an inner method like _store()

有帮助吗?

解决方案

While I think @Christophe's answer is the simplest solution (and simplicity often prevails over everything else), I think there is, at least, one more alternative.

If OrderController is basically the same for all three contexts but for some specific behaviour, I would evaluate the possibility to make these specific behaviours parametrizable. In other words, make OrderController configurable so that I have only one Controller and N different configurations. In runtime, this's translated into 3 different instances of OrderController each of which with its own configuration.

If at some point, any of the contexts diverge so that the convention over configuration is not possible, we are still in time to extend the controller and implement a dedicated one. Or not extend it at all.

It's worth saying that polymorphism (or inheritance) is usually more coupling and constraining than composition.


They have two parts, the first part in authorising and validating the input, and the second part is doing the logic like storing the order. the second part is the duplicate code.

Controllers, ideally, have very little logic to override. Extending a super controller should result in 3 classes with almost no differences, so why not encapsulate the differences in components and make the controller configurable?

On one hand, validations and security are cross-cutting features that can be decoupled from controllers. On the other hand, business logic must be encapsulated in different components.

其他提示

Since both are order controllers, it could make sense to define an abstract controller that defines the properties and behaviors common to all your OrderController, and let your role-specific controllers inherit from it.

Edit:

Your updated question seems to suggest that the controller does two different things: on one side it manages/controls the input; on the other it manages the (persistent?) data.

The second part would typically be handled by a model in an MVC design. In such a design, the model would be shared between the controllers, thus avoiding the repetitive part in the controllers.

But it all depends on what else is done in the duplicate part beyond the store(). If it’s more than maintaining the model, then Laiv’s component based approach would certainly be a sound and robust approach.

许可以下: CC-BY-SA归因
scroll top