Clean architecture: use case mixing - clean-architecture

I'm trying to understand how clean architecture works, last project i had a user, he can add a payment card and buy a subscription (example use case), but when it's new user, add and buy integrated as one step
Use case sample
According to what has been read, it should have two "Interactors", one "AddPayment" and "Purchase", , but... how can I mix:
The user can do both separately, but when he is new, in registration process he adds the payment method and makes the charge in one step,
I think I should have an "Add and pay" use case, but it would have repeated code and a broken paradigm, I see these options:
Make a third use case with repeated code
Merge from controller
Make a use case that calls the other two
How have you solved it?

I usually make a base use case that calls the other two. For this base use case I define a new request model that contains the request models of the others . The same applies for the response model. But sometime the request or response models have something in common and I create more condensed models.
I think that a base use case fits best to the include relationship of the use case uml model.
+-----------+
| AddAndPay |
+-----------+
| |
V V
+-----+ +-----+
| Add | | Pay |
+-----+ +-----+
The AddAndPay use case also handles failures of one of the use cases. E.g. if pay fails you might not want to add a payment card. Maybe you must invoke a RemovePaymentCard use case then or your transaction boundary is the AddAndPay use case.

Related

What is the convention around derivative information?

I am working on a service that provides information about a few related entities, somewhat like a database. Suppose that there's calls to retrieve information about a school:
service MySchool {
rpc GetClassRoom (ClassRoomRequest) returns (ClassRoom);
rpc GetStudent (StudentRequest) returns (Student);
}
Now, suppose that I want to find out a class room's information, I'd receive a proto that looks like so:
message ClassRoom {
string id = 1;
string address = 2;
string teacher = 3;
}
Sometimes I also want to know all of the students of the classroom. I am struggling to think which is the better design pattern.
Option A) Add an extra rpc like so: rpc GetClassRoomStudents (ClassRoomRequest) returns (ClassRoomStudents), where ClassRoomStudents has a single field repeated Student students. This technique requires more than one call to get all the information that we want (and many if we wanted to know information for more than one classroom).
Option B) Add an extra repeated Student students field to the ClassRoom proto, and B') Fill it up only when necessary, or B") Fill it up whenever the server receives a GetClassRoom call. This may sometimes fetch extra information, or lead to ambiguity according to what fields are filled up.
I am not sure what's the best / most conventional way of dealing with this. How have some of you dealt with this?
There is no simple answer. It's a tradeoff between simplicity (option A) and performance (option B), and it depends on the situation which solution is best.
In general, I'd recommend to go with the simple solution first, unless your measurements demonstrate that it leads to performance issues. At that point, it's easy to add repeated Student students to ClassRoom and a field bool fetch_students [default=false] to ClassRoomRequest. Then clients are free to continue using the simple API, or choose to upgrade to the more performant API if they need to.
Note that this isn't specific to gRPC; the same issue is seen in REST APIs, and basically almost any request/response model.

Which architectural pattern allows dynamic instantiation of multiple views per model?

Let's say I want to build a calendar app (in HTML + JS) where the user can see one week at a time.
The user should be able to define events, e.g. Mondays from 1:00 - 3:00:
+---------+---------+ +---------+
| Monday | Tuesday | ... | Sunday |
+---------+---------+ +---------+
0:00 | | | | |
+---------+---------+ +---------+
1:00 /////////// | | |
//MyEvent//---------+ +---------+
2:00 /////////// | | |
+---------+---------+ +---------+
...
+---------+ ...
23:00 | | ...
+---------+
I thought about creating one model, EventModel and one view, EventView, and wiring them up by the usual MVC approach. An eventView would be rendered on top of the calendar grid as a separate layer, so it would be able to autonomously maintain its size and position.
EventModel has nothing but three attributes, startTime, duration and title.
Things become more difficult though, if the user defines an event that spans over midnight, like Mondays 23:00 - Tuesdays 2:00:
+---------+---------+ +---------+
| Monday | Tuesday | ... | Sunday |
+---------+---------+ +---------+
0:00 | /////////// | |
+---------//MyEvent// +---------+
1:00 | /////////// | |
+---------+---------+ +---------+
2:00 | | | | |
+---------+---------+ +---------+
...
+---------+ ...
23:00 //MyEvent// ...
+---------+
Now two views bound to the same model are needed.
Naturally, all changes in the model should be reflected in the view(s). Note that the number of views required for a single model may change (1 to 7) as the startTime or duration attributes are updated.
In other words: Changes in the model need to trigger instantiation/destruction of views for that model.
I see two possible approaches for achieving this:
Use some controller logic that dynamically generates/deletes the required number of views and models, and keeps the models in sync with each other
... which seems like a bad idea since that would require a lot of fumbling as well as an additional class of models.
or
Stick with one model and build a View proxy that acts like one view, but internally controls the required number of "subviews".
The second approach is much more appealing to me. I wrote some pseudo-code to illustrate it:
ViewProxy.onModelChange(model) {
if (model.hasChanged("startTime") or model.hasChanged("duration"))
this.destroySubviews()
subStartTimes[] = getSubStartTimes(model.startTime, model.duration)
subDurations[] = getSubDurations(model.startTime, model.duration)
subViews[] = this.buildSubviews(subStartTimes, subDurations)
subViews.bind(model, "title")
endif
}
The downside with this is that the subviews unnecessarily get destroyed and re-built on all model updates (except title only), unless I include additional logic - which is not so trivial. Also, this proxy is some weird thing between controller and view, which somehow makes me feel uncomfortable.
So my question is: Is there a standard approach to this problem? If not, which issues may arise with the above solution? Any other solutions?
Your EventModel maps to multiple View elements because your model contains multiple sub elements (EventDayModel).
Sure, the input definition of the EventModel might be title, startDateTime, duration, but the model conceptually consists of one or more EventDayModel elements (each containing a startTime and duration).
So instead of maintaining a one to one mapping between the EventModel and the EventViewProxy (which effectively controls the view elements corresponding to each day), why not just subdivide the EventModel into a list of EventDayModel, each which have a one to one mapping to EventDayView elements.
When you change an EventModel, it's EventDayModel list is recalculated and the corresponding EventDayView elements are updated.
After searching around for a while, I found that the answer is The Composite Pattern.
So, the idea is to treat all the event view snippets of one events as a single view that manages several subviews.
As for data binding, I guess this is not possible without a bit of logic in the view. In my case, I decided that the view itself would be composed (think Composite pattern!) of a smaller MVC hierarchy. So the models inside the view are bound to the subviews by simple data binding, and the ViewProxy manages updates in the underlying model.
You could emulate Google Calendar structure which re-renders the calendar rather than destroying and recreating subviews.
If you use Angular then you could tie up scope variables and put a watch on the model attributes to update the view properties.
Each view could be seen as "div box" positioned depending on the start and end times. If the user deletes the event then the associated "div box" and the event object is removed from list of events.
If there is an update with to event then we update the coordinates of the "div box" depending start and endtimes.
The resource below is to show the model structure used by google calendar.
https://developers.google.com/resources/api-libraries/documentation/calendar/v3/java/latest/com/google/api/services/calendar/model/package-summary.html

Cucumber Transforms for Multiple Variable Scenario Outline Examples

I have a set of functionally similar websites that I want to write cucumber specs for to drive both development, and selennium browser tests. The site are in different languages and will have different URLs, but will have mainly the same features.
An example scenario might be
Scenario Outline: Photo Gallery Next Action
Given I visit a "<photo-gallery-page>"
When I click "<next-button>" in the gallery
Then the photo should advance
Examples:
| photo-gallery-page | next-button |
| www.site1.com/photo-gallery | Next |
| www.site2.com/la-galerie-de-photos | Suivant |
This is fine when I have a small number of scenarios and examples. However I'm anticipating hundred of scenarios and fairly regular launch of new sites. I want to avoid having to edit each scenario to add examples when launching new sites.
I think I need to store all my example variables in a per site configuration, so that I can run the same scenario against all sites. Then I can add new configurations fairly easily and avoid editing all the scenario examples and making them unreadable.
site[:en].photo-gallery-page = 'www.site1.com/photo-gallery'
site[:fr].photo-gallery-page = 'www.site2.com/la-galerie-de-photos'
site[:en].next-button = 'Next'
site[:fr].next-button = 'Suivant'
One option would be to store this config somewhere, then generate the site specific gherkin files using a script. I could then run these generated gherkins which would contain the required examples
I'm wondering if there's an easier way. My other idea was if I can use table transforms to replace the example blocks. I've had a read, but as far as I can tell I can only transform a table (and replace it with a custom code block) if it's an inline table within a step. I can't transform an examples block in the same way.
Have I understood that correctly? Any other suggestions on how best to achieve this?
I wonder if there's a better way... This all feels very brittle.
What if:
Given I follow a link to the gallery "MyGallery"
And the gallery "MyGallery" contains the following photos:
|PhotoID|PhotoName|
|1 |MyPhoto1 |
|2 |MyPhoto2 |
And the photo "MyPhoto1" is displayed
When I view the next photo
Then the next photo "MyPhoto2" should be displayed
Note that you've taken out the notion of button names, etc. - implementation details that are presumably better defined in your step definitions. The behaviour you're defining is simply going to a gallery, viewing an image, requesting the next one, viewing the next image. Define how in your step definitions.
There's some reading I found very useful on this topic at http://cuke4ninja.com/. Download the PDF and check out the web automation section (it details the web automation pyramid).
To address your configuration problem, maybe you could define some kind of config. class and supply it to the step definition files via dependency injection. You could make it site specific by loading from different config. files as you suggested in its constructor. Step definitions could pull the relevant site specific data from the config. class' properties. I think this would make your scenario is more readable and less brittle.

What is the best strategy for BDD testing which relies on data

What are some strategies for writing BDD tests, which can test behaviour that relies on certain data being in the system?
For example, say I was working with the following scenario:
Feature: Search for friend
In order to find a friend
As a user
I want to search my list of friends
And filter by 'first name'
How could this test ever succeed unless/until some "dummy" friends had been entered into the system?
More to the point, what "dummy" criteria would the test utilize?
Should I hard-code the name of a friend, assuming it to already exist in the database?
But what if I move my code to a new environment with a fresh database?
Or, should I write code to manually insert dummy data into the system prior to executing each test?
But this would be modifying the internal state of the application from within a test framework, which seems like a bad approach, since we're supposed to be treating the program as a black-box, and only dealing with it through an interface.
Or, would I create other scenarios/tests, in which the data is created using an interface of the program?
For example, 'Feature: Add a new friend to my list'. Then I could run that test, to add a user called 'Lucy', then run the 'Search for friend' tests to search for 'Lucy', which would now exist in the database.
But, then I'd be introducing dependencies between my scenarios, which contradicts the common advice that tests should be independently runnable.
Which one the best strategy? Or is there a better way?
You would use the Given clause in your scenario to get the system into the appropriate state for the test. The actual implementation of this would be hidden in the step definition.
If the data is going to shared across your scenarios then you could have in a background step:
Background:
Given I have the following friends:
| andy smith |
| andy jones |
| andrew brown |
To add these friends you could either insert records directly into the database:
def add_friend(name)
Friend.create!(:name => name)
end
or automate the UI, e.g.:
def add_friend(name)
visit '/friends/new'
fill_in 'Name', :with => name
click_button 'Add'
end
For the scenarios themselves, you would need to think of key examples to validate the behaviour, e.g.:
Scenario: Searching for a existing person by first name
When I search for 'andy'
Then I should see the friends:
| andy smith |
| andy jones |
But I should not see "andrew brown"
Scenario: Searching for a non-existing person by first name
When I search for 'peter'
Then I should not see any friends
You're correct that tests should be independent, so you shouldn't rely on other scenarios to leave the database in a particular state. You will probably need some mechanism to clean-up after each test. For example, the 'database-cleaner' gem if you're using Cucumber and Rails.
You are referring to BDD and Integration style of testing. If you use a decent ORM (NHibernate?) you can create an in-memory database before each test runs and clean it up after the test succeeds and since the db is in memory, it won't take much time comparing to running it on a real database.
You can use the pre/post test hooks to fit in the data necessary for your scenario and clean it up afterwards so that your tests can be run without depending on each other.

Granularization of models?

I'm developing a CMS largely based on Zend Framework components. Some of the database tables for this CMS are as followed:
site
| id | name |
-------------
locale
| languageCode | regionCode |
-----------------------------
site_locale // link sites with locales
| siteId | languageCode | regionCode | isActive | isDefault |
-------------------------------------------------------------
I have a model named Site which consists, amongst others, of the following methods:
getId()
getName()
listLocales() // list all locales for this site
I'm kind of on the fence on how granularized I should define models:
One option would be to return SiteLocale objects/models (in other words a DB table representation) from the listLocales() method, where these SiteLocale objects contain the following methods:
getSite() // returns the Site model
getLocale() // returns a Zend_Locale
isActive() // is this locale active for the site this model represents?
isDefault() // is this the default locale for the site this model represents()
The other option would be to simply create the following methods in the Site model, and be done with it:
getDefaultLocale() // simply return the default site locale as Zend_Locale
listActiveLocales() // simply return all active site locales as Zend_Locales
listAllLocales() // simply return all site locales as Zend_Locales
What do you feel is the right way to go? And why?
Furthermore, would the first option (or perhaps even both options) violate the Law of Demeter?
EDIT (22 jan)
Although I like Jeff's answer, Im still open for new/other perspectives.
First, regarding the database tables: You could probably normalize the database further. There's duplication between the locale and site_locale tables. Of course, I'm not seeing the big picture here so there might be something behind the way you've done it.
Frankly, either option is fine. I would choose the design that makes your code more readable and maintainable. For instance, if you chose the first option, would you end up with loops like this all over the place?
site_locales = site.listLocales()
foreach (site_locale in site_locales) {
if site_locale.isDefault() {
do_something(site_locale.getLocale())
}
}
If so, then I'd avoid it and go with the second option and end up with:
do_something(site.getDefaultLocale())
This is much more understandable with a quick glance. Maybe it'd even improve your site's performance.
However, if you think you're going to do a lot of work that utilizes lists of SiteLocales in the future, but you don't know exactly what you're going to do beyond getDefaultLocale(), listActiveLocales(), and listAllLocales(), then perhaps the first option might be ideal. Or you could even use a combination of the two.
As for the Law of Demeter, it's more like the Guideline of Demeter. It's OK to break any rule as long as you do it consciously, understand why you're doing it, and understand the consequences, if any. For instance, if breaking the law leads to more maintainable and readable code, yet you still preserve a high-level separation of concerns in your application, it's generally OK. So I wouldn't worry about whether or not either option breaks the law.

Resources