Table Of Content

We need more resources to remind us not overcomplicate software architecture. It will become complicated enough, module after module, layer after layer. The author argues that if your code throws an exception, you force all callers of that code to know how to handle this exception. Yet, in many cases, callers don’t know what to do about the exception which is thrown. He says we should define our functionality so we never need to throw an exception.
Chapter 19 — Software Trends
Otherwise, you are better off implementing the system without that particular element. For example, a class can reduce complexity by encapsulating functionality so that users of the class needn’t be aware of it. Classitis may result in classes that are individually simple, but it increases the complexity of the overall system. Small classes don’t contribute much functionality, so there have to be a lot of them, each with its own interface.
What I learned this book
Technical debt and architecture debt also don't get much mention or discussion, which is in contrast to my day to day work. It would be nice to see a later version touch on these topics, as well. The book is an easy read, thanks to its short sections and good bolding. Most importantly, the book stays humble, does not try to convince, but offers perspectives backed by easy to follow examples.
Lower-level comments add precision
To add to this, we haven't completely identified all of the issues we will confront. In essence, we still have to discover the Unknown Unknowns as we cautiously proceed. There are also a few weaker chapters towards the end of the book, for example Code Should Be Obvious and Software Trends. Code Complete has a lot more to say about names, and does it better. However, I really liked the story of how a too generic variable name (block) caused a bug that took six months to find. In a lot of places, the author uses comments and documentation interchangeably.
Do the Thing: Philosophy Teaching with Practical Workshops (guest post) - Daily Nous - Daily Nous
Do the Thing: Philosophy Teaching with Practical Workshops (guest post) - Daily Nous.
Posted: Tue, 18 Jul 2023 07:00:00 GMT [source]

Tradeoffs when combining or separating implementations within modules or interfaces (Chapter 9) is an interesting debate that I don't know of a single best answer. We share this view with John, who also agrees the best solution will be context-dependent. John collects a few rules of thumbs he suggests to use when deciding to combine or separate. Combine when it makes for a simpler interface, to reduce duplication or when implementations share data/information. Software design is a critical aspect of developing reliable and high-performing software applications.
And the answer to the question what is the most complex problem in Computer Sciences.
While event-driven programming is certainly more complex, due to no clear flow of control, in real-world scenarios, this is a necessity. Both in the case of distributed systems, as well as multi-threaded environments, there is no other option. John's suggestion to add a comment for event handlers doesn't cut it in my book. Instead, monitoring errors, alerting (for backend code) and logging, uploading, and analyzing logs (for client-side applications) is one way to stay on top of the system working correctly at all times. Much of modern programming, from messaging services to frameworks like Fx is moving towards an asynchronous model, where dealing with this complexity is part of the job. A strong stance against exceptions (Chapter 10) was an interesting read.
Large-scale programming styles
Ousterhoutdiscusses the different types and causes of complexity, and then varioussoftware design considerations and their relationship to complexity - patterns,antipatterns, questions to ask, etc. While the book does a good job covering architecture concepts when writing code, there are several areas that it does not touch on. Most of these are outside the scope of the software design course itself. The importance of good and simple naming (Chapter 14) mirror my experience on how simple names often mean simple functionality. Complex names - or difficulty to name something - is usually a code or architecture smell.
If you're interested in whether to read this book, my recommendation is that you probably should, for a few reasons I list in my conclusion. When you’re performing a code review on a class, smell around for special purpose code mixed with general purpose code. This mixture represents an opportunity to split off the general purpose code into something more reusable. But yours is a great review and a valuable service to the IT community that increasingly finds itself facing Technical Debt to the point of bankruptcy. Like reusing a common class, consistent naming lessens cognitive load by enabling readers to quickly draw assumptions when they see the name in a different context because they have already seen it in one.
Chapter 2 — The Nature of Complexity
The book doesn’t focus on a specific programming language or framework but rather presents general software design ideas. "Exception handling is one of the worst sources of complexity in softwaresystems". They can leak abstraction details upwards, making for a more shallowabstraction. Programmers are often taught that they need to handle exceptionalcases, leading for an over-defensive programming style. One pitfall is that complexity in software development is incremental.
If the code is so complex, we need to comment on it; maybe we can rewrite it to be more straightforward and understandable. Most people use a tactical approach, where the goal is to make something work. However, the result is a bad design with a lot of tech complexity, which usually results in spaghetti code. Complexity is not a single line but many lines in a project, which we overlook as a whole. His recommendation is to take a strategic approach where the working code is not the only goal, but the goal should be great design, which simplifies development and minimizes complexity. It involves breaking down software systems into smaller, independent modules or components, each responsible for a specific functionality or feature.
In some examples, the author recommends that some domain concepts are explained in the comments, in case the reader isn’t familiar with them. However, for well-known domain concepts, the reader will almost certainly already be familiar with those concepts. Even if they are not, the comments aren’t the right place to explain them. If the lower index is below zero, or the higher index is beyond the string length, an IndexOutOfBoundsException is thrown. This forces the caller to handle these cases before calling substring.
"If you reduce the number of methods in an API without reducing its overallcapabilities, then you are probably creating more general-purpose methods." An abstraction is asimplified view of an entity which omits unimportant details, making it easierfor us to think about and manipulate complex things. It is more important for a module to have a simple interface than a simple implementation. That being said, we have to be wary of Classitis a term I have come to appreciate and can relate too, as I have worked on many software systems in the past that actually have this issue.
Instead you can define it to return the characters of the string (if any) with index greater than or equal to beginIndex and less than endIndex. That way no exception needs to be thrown, which greatly simplifies the usage. Python does something similar when returning an empty result for out-of-range list slices. An example is when you have implemented a message protocol with a sender and a receiver.
A singleshortcut or tactical decision that adds complexity won't have much impact, butsmall decisions can accumulate to dozens or hundreds of things that do have animpact. Then refactoring becomes a big task that you can't easily schedule withthe business, so you look for quick patches, and this creates yet morecomplexity, which requires more patches, and so forth. Ousterhout advocates for a strategic approach to software development, ratherthan a wholly tactical approach. This essentially just means ongoing, regularinvestment of some of your development time towards system design, rather thanjust working code. When building software systems, the core challenge is managingcomplexity.
You can apply the ideas in this book to minimize the complexity of large software systems so that you can write software more quickly and cheaply. For people who have less experience in software development, the remaining of the book will also be practical. The parts on writing comments before coding, and comments complimenting the code are decent strategies to start with. Those with more experience under their belt my disagree with some of the recommendations.
It's more important for a module to have a simple interface than a simpleimplementation. If you have complexity that is closely related to your module'sfunctionality, you should consider pulling that complexity into the module'simplementation. Ousterhout's most often-used approach to this problem is to introduce a contextobject, which stores the application's global state - anything that wouldotherwise be a pass-through or global variable. They are not an ideal solutionbecause they have a lot of the disadvantages of global variables, but they canreduce the complexity of a method's signature.
No comments:
Post a Comment