🗞 Stream Recap: Tell—don't ask, Hot Seat Pair Programming
Our Tech Journey #6—Here's what you missed
Thank you to the ~45 live attendees. Over 350 people have now watched the show a week later.
Part 1—Pairing with Adrian
Part 2—Hot seat with an audience participant
Talking Points
Adrian: “I found helping others is where I can really scale. I solved so many of my teams in the past, so many business problems that I found out helping others suits me more at the moment.“
“We’ll be doing experiments with streaming on other platforms like Twitch and X.“
“Tell—Don’t ask (TDA) is a concept that originates from the ‘99 book The Pragmatic Programmer by David Thomas and Andrew Hunt.“
Denis: “When I coach refactoring, design, TDD and architecture I find engineers who apply TDA being delighted by the practice and how easy it is to learn.“
“Tell—Don’t ask is the best principle and refactoring skill to have to transition easily from poorly practised design in an object oriented language to proper object oriented design.“
“Aligns well with functional paradigms found in frontend frameworks and CQRS on the backend. However, it also suffers from their counterpart bad practices.“
“Freshman engineers go down the wrong path of OO design when their first taste with OO is public static main and creating a new class to escape static scope.“
“Decision-making with an object’s state should not be external to the instance of the object. This induces implicit design requirements for leaky abstraction. A function should be ‘honest’. An object’s state should be ‘encapsulated’.“
Recordings
Highlights (AI generated)
Part 1
The "tell don't ask" principle in object programming should be applied to AI in programming tools, in order to improve effectiveness and minimize unexpected side effects.
00:00 Adrian and Denis are transitioning to mentoring and helping others, discussing upcoming guests and the concept of "tell—don’t ask" in object-oriented programming.
Adrian is transitioning from CTO/strategic to engineering work, focusing on mentoring and helping others with their problems.
Denis discusses the idea of "tell—don’t ask" in the context of object-oriented programming and seeks opinions from the audience.
The concept of "tell—don’t ask" in object-oriented programming is a valuable and easy skill to learn, serving as a litmus test for transitioning from writing code in an object-oriented language to true object-oriented programming.
15:01 Denis explains "tell—don’t ask" in OOP, the shift to functional programming, and the importance of structured design in JavaScript frameworks.
"Tell—don’t ask" in object-oriented programming and the use of classes in JavaScript frameworks.
We discussed the shift towards functional programming and the perception that more people are embracing it, especially in the context of front-end development with frameworks like Angular and React.
We explored the importance of object-oriented programming and the need for a structured approach in the design phase.
20:38 Use "tell, don't ask" principle in OOP to avoid procedural code issues and double namespacing problem in Java, and focus on placing code within the appropriate class.
Place code within the appropriate class in object-oriented programming, highlighting the common mistake of writing code outside of the class.
People often misuse classes in procedural code, leading to issues with object-relational mapping and the necessity of keeping certain properties private.
Create a class that declares the usage scenario of the behavior, rather than tying it to specific data, in order to avoid exposing unnecessary details and to allow for flexibility in loading and filling data.
Use the "tell, don't ask" principle in programming to avoid asking for information and instead directly instruct the program to perform actions.
JavaScript mixes functional and class-based paradigms, while Java has a double namespacing problem, making it a disservice to junior engineers starting their learning journey in tech.
The concept of "tell—don’t ask" in object-oriented programming means telling the object what to do rather than asking for its data.
30:22 Object-oriented programming emphasizes the "tell don't ask" principle, with functions having specific purposes and objects managing their own state and behavior.
The function has a state dependency on a car, so it should be placed with the car and the getter can be removed.
Functions with a monotonic structure and only one parameter are necessary for mapping, reducing, or filtering in functional programming, as seen in examples like calculating prices and sending emails.
Function or method should have a specific purpose, not multi-purpose, following the principle of least astonishment.
Functions should have one mandatory property and optional options, but these options should not have unexpected side effects and it's better to have zero to two properties per function to avoid messiness.
Objects in object programming should manage their own state and behavior, following the "tell don't ask" principle, which means telling the object what to do instead of asking for its state.
The speaker discusses the importance of context in object-oriented programming and the need to dedicate functions to specific objects rather than using standalone functions in procedural code.
37:53 Standalone functions vs. higher order objects, organizing code in classes, using mail service for emails, importing templates for API functions, and implementing meaningful guards for error management and validation.
Standalone functions require passing all necessary parameters and may involve using process or environment variables.
Higher order objects can be used in a global or module scope, but this can lead to issues with encapsulation and maintenance.
The speaker discusses the process of moving a standard helper function into a class in order to better organize and manage the code.
The speaker discusses the importance of organizing code in a logical order to reduce mental overhead and presents a scenario for using a mail service to send emails.
Import a template from an external source, such as Puck or SendGrid, to use as an API function for creating a friend request template.
Assume the presence of guards for error management and schema checks, and implement meaningful guards at the beginning of the function for reusability and to ensure proper validation of user input.
45:16 Defining user types and accessing properties in OOP systems, generating getters and setters, validating email addresses, utilizing a mail service, handling request success, and the importance of return statements and context in object-oriented programming.
The speaker discusses the validation and execution of input parameters, as well as the creation of a message template for a mail service.
The problem is defining a user type and accessing its properties and methods in an object-oriented programming system.
Generate getters and setters for user information, validate email addresses, and utilize a mail service for sending emails.
Handle the success of a request by checking if it is true and then giving a toast to the user, and if not, sending an error message.
The speaker discusses the importance of using return statements in functions and the need for context in object-oriented programming systems thinking.
The speaker discusses the challenges of testing a function with encapsulated context and static mail service, which may lead to impractical testing and failures due to unexpected behavior.
53:52 Avoid unnecessary testing of external services in object-oriented programming and focus on telling classes what to do instead of asking for information, improving clarity and reducing coupling.
Avoid unnecessary testing of external services in object-oriented programming and focus on the function's behavior.
You can improve object-oriented programming by telling the class what to do instead of asking for information, reducing coupling and increasing clarity.
The problem is that the destination class still needs to have a Setter and a getter, and turning it around to make a receiver class instead of a sender class wouldn't fully address the problem.
In object-oriented programming, the concept of "tell, don't ask" allows for the use of properties within a class without the need to ask another class, and the problem lies in languages that do not have friendly concepts like JavaScript.
In object-oriented programming, the concept of "tell, don't ask" emphasizes that one class should tell another class to do something with its own properties, rather than asking about the properties.
The template should be part of the function itself, as there is no variability and it is not necessary to make it a dependency.
01:01:47 Object-oriented programming involves "tell—don’t ask" to avoid coupling and use asynchronous communication, with a preference for AI co-pilot despite some issues.
The sender sends a friend request to the receiver, who then has a method to receive the request, using a double dispatch method.
Create a sender function to send a friend request by telling the user class to call the receive email method with the sender's credentials.
Object-oriented programming systems thinking involves avoiding duplication and breaching encapsulation by passing information between classes without exposing it publicly.
The speaker discusses the importance of solving problems without exposing user properties and state through Getters and Setters, emphasizing the need for decoupling and communication via asynchronous ways like message queuing and microservices.
The concept of "tell—don’t ask" in object-oriented programming helps to avoid coupling and make systems more easily testable.
The speaker discusses the use of AI in coding and expresses a preference for using co-pilot, despite some issues with it.
Part 2
It is important to avoid creating a giant God object or enormous router
00:00 Adrian accidentally ended the stream but returned, emphasizing the importance of telling rather than asking in design efforts and discussing the redesign of a user entity and class encapsulation.
Adrian accidentally ended the stream, but he's back and waiting for everyone to return before continuing with the example.
The speaker starts the video with background music and then proceeds to engage with the audience before continuing with the exercise.
Design efforts should focus on telling rather than asking, avoiding overdesign and unnecessary abstraction, and not relying on polymorphism, classes, or inheritance.
Create a user entity with sender and receiver functionality, using polymorphic vertical behavior to avoid breaching encapsulation.
Denis discusses redesigning the class to encapsulate friend requests and separating out the email sending process.
Accidental red button press caused stream to go offline, had to send new link, invited Thomas to join on stream.
08:49 Engineers tend to create giant God objects or routers when designing systems with a user object, emphasizing the importance of understanding the business concerns and encapsulating commands in a public API.
Designing systems with a user object can lead to the problem of creating a giant God object or enormous router with all the user-initiated actions.
Thomas joined the speaker on stage, they discussed what he learned and where he would take it from there.
The speaker discusses the concept of encapsulation and the tendency for engineers to put everything into service classes, emphasizing the importance of understanding the hardware aspect of CPU and memory.
The speaker discusses how to communicate a friend request and email service to a user, using the example of writing code for the user to receive an email from a receiver.
The speaker discusses encapsulating commands in a public API and using a service to execute the commands.
15:51 CQRS and EventSourcing patterns separate command timing and execution, "tell-don't ask" simplifies user actions, and a message bus handles friend requests in a conference social space.
CQRS and EventSourcing patterns focus on separating the timing and execution of commands, allowing for more flexibility and independence in decision-making.
The speaker discusses the concept of "tell-don't ask" and how it simplifies the process by making the user or command do less stuff.
The speaker discusses the business context of creating a friend request command processor for a conference social space similar to Zoom.
The speaker discusses the concept of a message bus and its functionality in handling friend requests and sending emails.
The speaker demonstrates creating a class and encountering the problem of continuously being asked to expose private information.
22:51 The speaker discusses creating support for the CQRS idea, processing commands through a message bus, and the importance of consistent database and configuration for mail services in programming.
The speaker discusses the process of creating support for the CQRS idea and closing the loop by creating an email that is sent and received in the command process.
The speaker discusses the process of receiving and processing commands through a message bus and the need for establishing locality in order to communicate asynchronously with send email.
The speaker discusses the importance of having a consistent database and configuration for mail services in programming, and the potential challenges of decoupling code.
Accidental structures can lead to a dilution of the type system and a lack of clarity in the main decision and state transfer in GraphQL servers.
The speaker discusses the concept of friend requests and the structure of friends and user IDs.
The speaker discusses creating new friends and validating their IDs in order to create a strong value object in DDD terminology.
31:26 Object orientation and the concept of friend lists are discussed, emphasizing the importance of shaping concepts in a way that is understandable to humans and the unnecessary use of adjectives in processing friend requests.
Friends list can be symmetric, with confirmed and pending friend requests separated, and this logic needs to be included in the context.
Object orientation is about shaping concepts in a way that is understandable to humans, such as envisioning a friends list and pending friend requests in a more conceptual and less technical manner.
The speaker discusses the concept of friend lists and the unnecessary use of adjectives in the context of processing friend requests.
Creating a separate process for creating and populating a friends list without using an ORM or entity setup.
Requests are not interesting unless they are bidirectional, and the sender's information may not be disclosed in a friend request.
36:46 Using sender and receiver IDs as objects instead of numbers, the speaker explains the "tell, don't ask" concept in programming and emphasizes the importance of encapsulating behavior in Java space for improved code readability and simplicity.
The speaker discusses the semantic distinction between sender and receiver IDs in an array, and provides examples of how to use this distinction in a friend request scenario.
ID and receiver ID can be represented by objects, which are more intuitive and natural for the brain to think about, and can be defined as strings or UUIDs without the previous limitations of being numbers.
The speaker explains the concept of "tell, don't ask" in programming, using an example to clarify the process of checking for equality between sender and receiver IDs.
Make objects immutable and keep related properties together to simplify code and improve readability.
Encapsulating behavior in Java space may seem mechanical, but it is rich in meaning and semantic, unlike typical hash code and equals implementation.
42:41 Use "tell-don't ask" approach in coding for handling friend requests, validate requests, send emails for new requests, and confirm requests, making the API asynchronous friendly and idiom potent.
Focus on using a "tell-don't ask" approach in coding to avoid issues with personal identity and friend requests.
The speaker discusses the concept of friend requests and how to model it in a database using a graph or set database, and suggests using a simple API to handle friend requests.
Validate friend requests when they come in, send an email for new requests, and confirm friend requests from the other direction.
The decision is whether to send an email, and if it's the first contact, then send the email, using the "tell-don't ask" pattern to handle friend requests and avoid duplicating or sending emails accidentally.
Make the API more asynchronous friendly and idempotent to make testing easier, without going into detail about writing the code.
Archive
You can always find the archive of the Thursday shows on the Stream Recap section and the Wednesday episode on the SnackableCTO. We’re still figuring this out.