-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I added my comments to the guidelines (only). #2
base: main
Are you sure you want to change the base?
Conversation
My intend was to leave your text untouched, but I fixed 1 or 2 typos. I used quote markup for my stuff.
You bring up some very interesting points that warrant reflection. Give me some time to contemplate some of them before giving you an answer. I have a job interview tomorrow, so you can expect me to craft an answer after that. |
I have a few questions so i can get a clearer picture not only of the problems On Flow-Based Organization On Natural Bounderies On Flow of a Feature On Readability and Visitor Pattern On Reuse On Error Handeling On the Last Two Points On Allowing and Dealing with Cross-Cutting Locally On Following Idioms On Constant Complexity Scaling On Proposals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added my reply to your comments whithout adding your comments into the text.
Feedback on your reply which I cannot relate to a text location:
On Natural Bounderies.
If it be populating a database or authenticate a password or
id. does that make sense?
Yes, it does make sene.
On Proposals
On the other suggestion, on times when it might be necessery:
I do not know, what you are refering to.
## Fundamental Principles | ||
|
||
### 1. Flow-Based Organization | ||
Code should be organized around complete flows of functionality rather than arbitrary technical boundaries. Each significant feature should be treated as its own "river", a coherent path from beginning to end. The goal is to maintain locality, visibility and comprehensibility of the entire process. | ||
|
||
> If those technical boundaries are indeed *arbitrary* I fully agree. Often they are required by the techniques used. If those are strictly necessary to achieve the goal is another discussion. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Examples are requirements like
- test-ability (might require dependency injection to get a mock where it is required.
- Extensability (Others should be able to extend/adapt the flow at runtime)
- Consistency across flows (10 flows should behave similar)
@@ -20,28 +34,58 @@ Systems should be divided along natural feature boundaries, like a watershed con | |||
4. Use clear section comments to guide readers through longer flows | |||
5. Keep feature flows independent of each other where possible | |||
|
|||
> If *flow of a feature* is the only or main principle of structure, I fully agree. But, as I hopefully have commented in the main essay, I believe other principles are needed as well. | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe your reply on this revers to the River-Guidelines yourself and that my comment means that is it not yet complete and should be extended.
My comment addresses something else. The whole "The River" approach assumes a certain main principle of structure. If I draw the program it will always be a flow-chart. My experience differs. In some applications the flow-chart is a good choice and the The-River is a good principle. It then makes sense to follow your guidelines.
But on other occasions other models are better suited to solve the problem. I have yet to elaborate on that and what other structures I mean.
4. Keep abstractions close to where they're used, preserving context | ||
5. Accept similar patterns in different contexts rather than forcing reuse | ||
|
||
> *Forcing* reuse does not make sense, agreed. If you scale the complexity of the problem domain, you will encounter the true *need* for reuse, because you will have to check 99 flows, if they also contain the bug you just fixed in 1 of 100 flows (I am aware that there are draw-backs on the reuse which might be harder to handle). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I accept your reply.
But, take a change in requirement. The resolution of the screen in use will change and those flows do contain actual pixel numbers (which could have been avoided in the first place, but have not). One flow contains: First column (100px) second column (150px) third column (remaining). When 500 pixels were available this is just fine. Now 1000 pixels are available. and I have to double those numbers.
Other flows handled the usage of the availble screen estate in their own independant way.
Contra Flow: How lovely it would have been if they all used a single shared parameterized screen, so I only had to change that one screen.
Pro Flow: How aweful it would have been if I had only a single shared parameterized screen to handle the requirements of 100 different flows. No one will understand the resulting parameters and any change to the screen might break many flows.
I had to deal with such a change for the Porsche Workshoptester.
2. Provide rich context in error messages by leveraging local knowledge | ||
3. Design flows to contain and isolate failures | ||
4. Make error states and recovery paths visible within the main flow | ||
|
||
> I think the last two points have not been shown/discussed in the essay. If we were to discuss them, examples of what that means for you were required. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean how to design flows to contain and isolate failiurs and making
error states and recovery paths has not been shown/discussed in the essay well
enough?
yes
### Cross-Cutting Concerns | ||
1. Treat logging, security, and monitoring as part of the local environment | ||
|
||
> This might hide the flow. How do you see/mitigate that? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I mean: The flow in one of your examples is:
// Parse the request
// Validate the parameters
// Query the database
// Update the database
// Construct the response
If you add logging, assertions, more checks for security and monitoring additions all this cross cutting concers will clutter up the function and hide the flow. I might not see the actual parsing in the code, because most of the code after the // Parse the request
will no longer try to parse the request, but handle those other concerns.
3. Accept that similar patterns may repeat across different flows | ||
4. Focus on clarity and completeness within each flow rather than global consistency | ||
|
||
> Agreed, but: Global consistency can in turn increase readability across team members and thus maintainability. Following some idioms is ok. | ||
If global consistency is required (e.g. You have to do C before A before B) to make things work, maintenance becomes hard (because people will "forget" to do C or A). Avoiding such global consistency completely, might impose abstraction (I hide doing C and A, from whoever does B) and might obscure the flow. Where to settle for compromise between those extremes is a matter of actual situation. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you did not understand my comment. Or I did not understand your reply. Let me try to explain again.
To make things work I have to do C before A before B. If I understand the flow-principle I will have multiple functions which read:
r=C():
if A(r) == failure {
handleError();
B();
Maybe even with some flow specific stuff inbetween.
How do I ensure across a team or across myself over time (future-me might no longer know what current-me knows) that we always do C before A before B?
I could introduce a functional abstraction: A function that does the above, which I call in every flow. Problem solved.
But I have broken other flow-principles. The error handler is now further away from the context that it aims to report. I no longer have the freedom to move flow specific stuff inbetween those calls to A or B.
If it is already a well known fact to everyone on the team that of course you have to C(); A(); B();
then I might just live with the risk and call that an idiom that I might even put in some documentation or specific coding guideline somewhere.
2. Maintain constant complexity by isolating it within each flow while the system grows | ||
|
||
> I am not sure I understand: Does it mean all the statements in flow should be on the same level of abstraction, e.g. the problem domain? | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should not need any
other part of the system (hopefully) to deliver the feature it is designed for.
What would I see in a function which does need other parts of the system?
I find it hard to distinguish good from bad functions by that criteria.
My intend was to leave your text untouched, but I fixed 1 or 2 typos. I used quote markup for my stuff.
I still intend to add comments to the full essay, but this is all I managed today.
This should not be merged into main.