Open jdickey opened 8 years ago
We just got back from reimplementing prolog_core
to its new-and-for-now-shiny 0.2.0 release, making extensive use of Wisper rather than injecting dependencies directly. That seems a good and useful strategy to apply here.
Specifically, our approach to hexagonal architecture led us to envision a use-case class for a "landing page" to look something like
module Prolog
module UseCases
class CreateOverallSummary
def initialize(current_user:, repo:)
# ...
end
def call
# ...
end
end # class Prolog::UseCases::CreateOberallSummary
end
end
The "repo" being injected into #initialize
would have been the Article
repository, which would serve as a persistence interface to a set of Article
instances, each of which would have an embedded User
entity for its author, as was implemented in PrologCore::Article
0.1.0's Article
entity.
Prolog::Core
0.2.0, in contrast, makes use of Wisper messages like :query_article_by_title
to get information on a particular article. (We can see right now that we'll need an 0.2.1 release which adds query_all_articles
to produce a collection of Article
instances.)
Against prolog_core
0.2.x, we'd probably want to use an even simpler public interface for our first use-case class:
module Prolog
module UseCases
class CreateOverallSummary
def call
# ...
end
end # class Prolog::UseCases::CreateOberallSummary
end
end
No explicit initialiser is needed to pass in the "current user" and "repo" parameters; when they're needed, they'll be queried for by Wisper messages. The key is going to be keeping the Wisper interface small, efficient and well-documented as it grows.
Future use cases similarly would "ask the world" for their outside collaborators rather than injecting them explicitly. We gain most of the benefit of the original, clean, hexagonal architecture without relying on concrete interface classes that must then be mocked and nested clumsily during testing and in live code.
EDIT
Actually, even better; there's no need yet for an 0.2.1 release because we're simply adding a new requirement to the persistent-storage interface _which isn't part of prolog_core
directly_; it's just made use of (and should be documented as such somewhere). prolog_core
no longer defines a "Repository" interface; it simply defines its interactions with *a persistent-storage provider.* That was easy :relieved:
We've been tearing down the list of "User-Eye View"-listed features, until we're confronted with the absolute need to define how we're going to present and store Article content. See Issue #16.
"User-Eye View" items 11, 12, and 14 are UI details wrapped around Item 13, "submit the new proposal after entering it validly". Whereas Meldd 1.0 will have at least three different types of proposal (for Edit, Challenge, and Inquiry Contributions), Meldd 0.5 will support only Edit Contributions. to be implemented in a new ProposeEditContribution
use case that will first appear in Gem release 0.6.0.
As described in two Wiki pages in the
prolog_core
repo (Getting to 0.5 and Architectural Rabbit Hole Avoidance Attempt No. 769), this Gem sets out the basics of how we're going to get from here (for an arbitrary value of here) to April Fools' Day.Gem Strategy
Paraphrasing ARAA 769:
When starting development of a new use case, open a new issue for that use case, and tag it with the
feature
label. In the opening comment, mention this issue by number, so GitHub will auto-generate a link for it here. This might not completely eliminate the need for a ginormous checklist, but it will at least defer it.User-Eye View
Reproducing that section of Getting to 0.5 for reference:
From a user perspective, it's going to take being able to:
and, bringing up the rear,
which can be deferred to a post-0.5 release without undue pain/wasted effort, as they are simply variations on by-then-existing items.
Oh, By The Way...
When reading those "user-eye view" requirements, bear in mind that much, if not most, of the verbiage describes user interface and other delivery-system artefacts, that the use cases remain categorically unaware of. For instance, the very first use case from a non-UI-centric standpoint might have been phrased as
This includes some concepts that either haven't been defined yet (permissions?) or which identify parameters that must be passed into the use case's command function. What's a "current user" when the person viewing the page hasn't yet authenticated to the system? We've just identified the need for a Guest User.