Ideas from "A Philosophy of Software Design"
The blog post highlights insights from "A Philosophy of Software Design" by John Ousterhout, focusing on reducing complexity, reconsidering component modularity, and simplifying exception handling for better software design.
Read original articleThe blog post discusses key insights from "A Philosophy of Software Design" by John Ousterhout, focusing on three main ideas that can help software engineers improve their design practices. The first idea emphasizes a zero-tolerance approach to complexity, highlighting that complexity accumulates over time and can lead to significant issues such as change amplification and increased cognitive load. The author suggests centralizing duplicated logic to reduce complexity. The second idea critiques the notion that smaller components are inherently better for modularity. Ousterhout argues that excessive subdivision can introduce unnecessary complexity and cognitive load, advocating for merging related functionalities instead. The third idea addresses the complexity introduced by exception handling, proposing techniques to minimize it, such as defining errors out of existence, masking exceptions, and aggregating exception handling. By implementing these strategies, developers can create more maintainable and understandable software systems.
- Emphasizing zero-tolerance towards complexity can prevent project issues.
- Smaller components may not always enhance modularity; merging related functionalities can simplify design.
- Exception handling can introduce significant complexity; reducing the number of exception handlers is beneficial.
- Centralizing duplicated logic can streamline code maintenance and reduce cognitive load.
- Techniques like error definition and exception masking can simplify error management in software systems.
Related
Htmx: Simplicity in an Age of Complicated Solutions
Erik Heemskerk discusses the pursuit of a 'silver bullet' technology in software development, emphasizing simplicity over complexity. He critiques over-engineering in front-end development, highlighting trade-offs in code solutions for better user experiences.
Beyond Clean Code
The article explores software optimization and "clean code," emphasizing readability versus performance. It critiques the belief that clean code equals bad code, highlighting the balance needed in software development.
On over-engineering; finding the right balance
The article highlights the importance of balancing specific-purpose and generic solutions in software design, advocating for flexible approaches while avoiding over-engineering that complicates code and maintenance.
The Rise of Worse Is Better
The text contrasts two software design philosophies: the MIT approach, which values simplicity and correctness, and the worse-is-better philosophy, which prioritizes implementation simplicity, suggesting a need for reevaluation in the Lisp community.
Good Software Development Habits
The blog post outlines software development habits that boost productivity, emphasizing small commits, continuous refactoring, frequent deployments, test-first approaches, and the importance of testability as a design indicator.
- Many commenters emphasize the importance of well-designed abstractions, noting that they should be easy to understand and use.
- There is a debate about the balance between simplicity and modularity, with some arguing that excessive modularity can lead to unnecessary complexity.
- Several commenters express a desire for more in-depth discussions on complex software design challenges beyond basic principles.
- Some readers appreciate the book's insights but criticize its theoretical depth and consistency.
- There is a recognition of differing perspectives based on programming backgrounds, particularly between functional programming and imperative programming.
In short:
A beautifully designed abstraction is easy to understand and use.
It is so trustworthy that you don't feel any need to worry about how it is implemented.
Finally, and most importantly, it enables you to reason with rigor and precision about the correctness of the code you are writing that makes use of it.
The trouble is that kind of thing's pretty much software development common sense - only the inexperienced don't know it.
The true difficulties of software development are often must gnarlier in my experience.
For instance, making architectural choices for large and dynamic software systems, such as say a cutting edge game engine - that can be really hard to get right, and there's not always a lot of sage advice out there for how to navigate it - and not just for game engines but for any equally or more complex software.
I guess my point being - I'd love to see more effort into addressing the hard design stuff, and less repetition of what's already been established.
I'd probably just make applyDiscount a static utility method that the two classes import and invoke on their own, at least until it becomes obvious that something more involved is needed.
First, it’s more about repetition/poor design than complexity. Second, creating a separate service class for applying a discount is adding unnecessary complexity. You’ll end up with a pile of DiscountService, TaxService, ShippingCostsService, and so on, and they will be sewn together like patchwork. It seems to be a common pattern in Java but surely there are better ways?
I read this book recently, one chapter at a time, and after each, reviewed the code for my current project, applying the principles to it in a re-write --- it helped a lot.
Highly recommended.
This book, as well as the data oriented design approach, is what made things right for me.
My impression is that there's some good ideas in the book, but it suffers from not being thorough enough on a theoretical level. Many definitions given are NOT consistently used, the book frequently falls back on discussing things in a very OOP centric way, and a lot of stuff came across to me as just opinion pieces.
Some stuff I found was excellent, like the notion of module depth.
When reading reviews on Goodreads, there's a similar disparity between people who really liked it and people who are critical of it.
This seems similar to how events are handled in a web-browser. Each element can handle its own event-handlers. But equally well there can be a single event-handler for each event-type in a containing element, perhaps at the top-level only.
If you define event-handlers of a given type for all DOM-elements of the page in a single location it becomes much more flexible to modify how and which events are handled and for which DOM-elements.
So we could say that "error" is just one of the event-types, errors can be or could be handled by the same mechanism as events in general are. Right? Or is there clear categorical difference between error-events and other types of events?
Maybe it comes from experience, but I would focus on understanding the business side first and the see if the abstraction is feasible (To be honest the first approach in the example is not even bad given that they are two "independent" business entities)
Related
Htmx: Simplicity in an Age of Complicated Solutions
Erik Heemskerk discusses the pursuit of a 'silver bullet' technology in software development, emphasizing simplicity over complexity. He critiques over-engineering in front-end development, highlighting trade-offs in code solutions for better user experiences.
Beyond Clean Code
The article explores software optimization and "clean code," emphasizing readability versus performance. It critiques the belief that clean code equals bad code, highlighting the balance needed in software development.
On over-engineering; finding the right balance
The article highlights the importance of balancing specific-purpose and generic solutions in software design, advocating for flexible approaches while avoiding over-engineering that complicates code and maintenance.
The Rise of Worse Is Better
The text contrasts two software design philosophies: the MIT approach, which values simplicity and correctness, and the worse-is-better philosophy, which prioritizes implementation simplicity, suggesting a need for reevaluation in the Lisp community.
Good Software Development Habits
The blog post outlines software development habits that boost productivity, emphasizing small commits, continuous refactoring, frequent deployments, test-first approaches, and the importance of testability as a design indicator.