Skip to main content
deleted 12 characters in body
Source Link

The use cases layer knows nothing about the views/presentation, and it provides functions and/or interfaces that are expressed entirely in terms appropriate for that layer, meaning, these do not assume anything about what kinds of views consume them - in principle, these should work equally well with a desktop GUI, a terminal, or a web interface, or IDK, some near-future AI that can reliably translate verbal commands into function calls. This is achievable, but in practice, because the presenter has to take the response from the use case and translate it to the GUI format, and vice versa, there's a cost involved, so your design is somewhat constrained by it in terms of how different the two representations arecan be.

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer). Sometimes, the role of a dependency-injected presenter can be fulfilled by a simple lambda (the abstraction in that case is the required function signature).

The use cases layer knows nothing about the views/presentation, and it provides functions and/or interfaces that are expressed entirely in terms appropriate for that layer, meaning, these do not assume anything about what kinds of views consume them - in principle, these should work equally well with a desktop GUI, a terminal, or a web interface, or IDK, some near-future AI that can reliably translate verbal commands into function calls. This is achievable, but in practice, because the presenter has to take the response from the use case and translate it to the GUI format, and vice versa, there's a cost involved, so your design is somewhat constrained by it in terms of how different the two representations are.

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer).

The use cases layer knows nothing about the views/presentation, and it provides functions and/or interfaces that are expressed entirely in terms appropriate for that layer, meaning, these do not assume anything about what kinds of views consume them - in principle, these should work equally well with a desktop GUI, a terminal, or a web interface, or IDK, some AI that can reliably translate verbal commands into function calls. This is achievable, but in practice, because the presenter has to take the response from the use case and translate it to the GUI format, and vice versa, there's a cost involved, so your design is somewhat constrained by it in terms of how different the two representations can be.

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer). Sometimes, the role of a dependency-injected presenter can be fulfilled by a simple lambda (the abstraction in that case is the required function signature).

added 4 characters in body
Source Link

Well, sure, but that doesn't mean that it all has to be implemented in the same class. In other words, you can think of the presenter as just a class (or a small set of functions + data types, if your approach is more procedural or functional, rather than OO) that you've extracted from your UI code so that you can write the presentation logic more cleanly, without getting bogged down with the details of how things are actually rendered, or the peculiarities associated with particular UI controls. And, as Doc Brown's answer points out, it also allows you to write unit tests for the presenter. The main drawback there is that doing this often requires some boilerplate that syncs the presenters and the views (thus data binding).

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer).

P.S. Also, a heads up: "entities" is another one of those overloaded terms that means all kinds of things in different contexts. In CA terminology, "entities" are also not simple behaviorless data structures, but proper objects that have functionality to them, that model the core business/domain concepts and capture the associated business logic.

Well, sure, but that doesn't mean that it all has to be implemented in the same class. In other words, you can think of the presenter as just a class (or a small set of functions + data types, if your approach is more procedural or functional, rather than OO) that you've extracted from your UI code so that you can write the presentation logic more cleanly, without getting bogged down with the details of how things are actually rendered, or the peculiarities associated with particular UI controls. The main drawback there is that doing this often requires some boilerplate that syncs the presenters and the views (thus data binding).

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer).

Well, sure, but that doesn't mean that it all has to be implemented in the same class. In other words, you can think of the presenter as just a class (or a small set of functions + data types, if your approach is more procedural or functional, rather than OO) that you've extracted from your UI code so that you can write the presentation logic more cleanly, without getting bogged down with the details of how things are actually rendered, or the peculiarities associated with particular UI controls. And, as Doc Brown's answer points out, it also allows you to write unit tests for the presenter. The main drawback there is that doing this often requires some boilerplate that syncs the presenters and the views (thus data binding).

In the "pull" variant, your presentation-layer code simply calls a method on a use case. In the "push" variant, you'd dependency-inject a presenter (which remember, is an implementation of an abstraction required by the use case) into the use case. (This is true even in a dynamic language where you don't actually have to inherit from a class/interface - there, the abstraction is the spec of this "output port" associated with the use case, even if it only exists in the documentation). This is fine because all the use case sees is the abstraction, which is "owned" by the use case, and in principle has no view-specific aspects to it (though in practice, sometimes that might not be entirely true due to the aforementioned cost, or simply because a choice of some framework forces you to pollute your use cases layer).

P.S. Also, a heads up: "entities" is another one of those overloaded terms that means all kinds of things in different contexts. In CA terminology, "entities" are also not simple behaviorless data structures, but proper objects that have functionality to them, that model the core business/domain concepts and capture the associated business logic.

added 4 characters in body
Source Link

PresenterThe Presenter is just a part of the UI layer

Presenter is just a part of the UI layer

The Presenter is just a part of the UI layer

Source Link
Loading