It is not the first time that I come across discussions about who is studying new technologies and how and how to cope with the huge stream of “innovations” that appear every year in the software industry. Once I have already answered this
question on a qvt, and after the
next question I decided to shape these thoughts in a more structured way.
If you look around, you might get the impression that the software development industry is taking such huge strides that there is no way to keep up with it. And if we consider the entire industry as a whole, then indeed it is. Somehow I immediately recall old Brooks with his
“Mythical Man-Month” , when he wrote in conclusion to his book about how the software industry changed in the mid-90s compared to the 50s. In those early years (yes, the 90s are already far away too, so to speak of the era of the birth of the industry forty years earlier) you could read
all the magazines (!) Of computer subjects that were published. Now, dozens of books appear monthly on only one of the popular technologies, and the number of articles simply does not count.
On the one hand, this makes it necessary to treat the choice of sources of information in a more conscious and prudent way. And it was this thought that prompted me to form the list of the
most interesting books on programming in general, and separately, the most
significant books on the C # language and the .NET platform . But in addition to high-quality information sources (a list of books it would be good to add a list of blogs, podcasts and video tutorials) an important quality of any programmer is the structuring and “reuse” of the knowledge gained.
')
By the nature of our activities, we often face problems of complexity. We are used to fighting it in a variety of ways; we create small proven building blocks, on the basis of which we build large software solutions, we abstract from insignificant details, hiding implementation details behind the public interface of classes or entire modules, we create hierarchies of classes for summarizing and reusing knowledge and effort.
But what if you try to draw parallels between generally accepted software design practitioners and our knowledge? Here, for example, task decomposition is perfectly applicable, both in programming and in training. We all know very well how easy it is to make everything difficult (sorry for the pun), if you mix in one method simple business logic and logic for working with C-lines. If the method requires a dozen more or less simple operations with strings, then it will be very difficult to understand what is going on in it because of all these strlen, strcpy, strcmp, strcat and many other operations, each of which may contain an error.
NOTE
It is considered that the main advantage of encapsulation is to protect the internal implementation of the class from external clients ; they say, thanks to the encapsulation, the “service provider” can change the internal behavior (or presentation) without affecting the clients. However, encapsulation is not a one gate game; In addition to the fact that the class can change its implementation, encapsulation allows unloading the client from unnecessary implementation details , making his (client) life much easier.Mixing fairly simple logic in one place along with a poorly designed abstraction, we get a combinatorial growth of complexity that will explode the brain even when writing code, not to mention its support. The same can be noted, for example, when discussing a certain task within a team, when the interlocutor throws a huge amount of information at you, most of which could be dispensed by both interlocutors. When learning something new, the same problem manifests itself even more acutely:
one step at a time is
John Skitt’s favorite approach in describing the capabilities of the C # language, which he successfully uses in his book
“C # In Depth” , and it’s this approach that makes him The book is easy to read and understand.

Abstractions form a hierarchy (*)
(*) This is a drawing from the book Grady Bucha
"Object-oriented analysis and design with examples of applications .
"Now let's look at another aspect of development that can be directly used in training. According to Grady Bucha - any complex system is hierarchical. It is the hierarchy and modularity that allow you to somehow cope with the incredible complexity of the simulated systems. And if you consider any modern technology, you can see that the number of layers in it will be huge, and that each of them is based on well-tested layers of the lower level.
Reuse knowledge on the example of WCF
Let's take WCF as an example.

No modern technology is a spherical horse built in a vacuum from basic concepts or other similar technologies. In fact, most of them are just a
new combination , well-proven and well-known concepts, and WCF is no exception here.
Modern technologies for building distributed applications are quite similar. All of them are built on the basis of proven patterns, use low-level transport protocols and, to some extent, struggle with misconceptions about distributed applications (Fallacies of Distributed Computing).
So, for example, if you have experience with .NET Remoting, then you can reuse it when switching to WCF: each of these technologies is such a “puff” cake, with the ability to configure and customize various levels. In both technologies, we can use different instantiations and concurrency methods, customize security, and manage serialization.
You can also reuse knowledge of low-level communication protocols, because sooner or later problems will start in your system that cannot be solved without WireShark and packet analysis. In addition, many problems or their solutions can be embedded in the very nature of the transport protocol, and without this knowledge you simply cannot make a reasonable decision whether to use binding based on the HTTP or TCP protocol in this situation.
The same applies to the “service” component of WCF. Service architecture is a separate aspect that can be explored outside of WCF (for example, using web services) and re-using it in the context of a new technology. Of course, each of the building blocks on which the technology is built can be used in a specific way, but knowledge of the fundamental principles will make it easier to understand the new technology.
NOTE
Once I tried to answer the question “What is WCF?” , Trying to use the method of knowledge reuse described here and make the most of analogies with WCF receivers, such as .NET Remoting and web services.Generalization of knowledge on the example of automatic memory management
In addition to hierarchy and reuse of low-level basic blocks, we can use another OOP mechanism to deal with the complexity: generalization and specialization using inheritance.
Inheritance is one of the main “business cards” of the PLO and one of the main mechanisms for reuse, so it is not surprising that they are often abused. When designing software, there is often a problem called “
premature generalization ” (premature generalization), where base classes with a certain behavior are introduced at too early stages of development, although it is not yet clear what is “common” in this particular case. For example, quite often you can see a hierarchy of 5 base classes for a simple class
Customer , although at the current stage it is not at all clear why this is needed.
NOTE
Bertrand Meyer very well described the reasons for this state of affairs in software design: “Arbitrarily or not, many training presentations create the impression that the structure of inheritance should be designed from the most general (upper part) to more specific parts (leaves). In particular, this is because the best way to describe the existing structure is to go from the general to the particular, from figures to closed figures, then to polygons, rectangles, and squares. But the best way to describe the structure does not mean that it is the best way to create it .
In an ideal world inhabited by perfect people, we would immediately discover the correct abstractions, derive categories from them, then their subcategories, and so on. In the real world, however, we often first discover a particular case and only then discover a common abstraction . ”Likewise, the situation is quite typical when the interlocutor summarizes his experience and knowledge gained in one project with one programming language to other projects and other programming languages. In essence, he summarizes this knowledge into the “base” classes of his knowledge, although at the moment these classes have only one “heir”:
I: I know that multiple inheritance is garbage!
He: Why?
I: Because it is not in Java , but I do not know other languages!It is rather rash to draw such conclusions if the only language I know is Java. Most likely, I can make more correct conclusions and structure my knowledge more consciously, having become acquainted with at least several languages that support multiple inheritance, such as C ++ and Eiffel.
Let us, as an example, consider several ways of automatic memory management and present them in a hierarchical form.

Automatic memory management is the most common concept, which falls under several special cases. For example, two most typical solutions can be distinguished, based on (1) garbage collection (2) and reference counting; at the same time, garbage collectors can use generations (generations) or not.
Each solution has its own advantages and disadvantages. Thus, memory management based on reference counting will suffer from “ring” dependencies (when object A contains a reference to object B, it contains a reference to object C, and it again refers to A), but it will ensure the determinism of resource cleanup. The garbage collector will solve the problem with cyclical references, but it will have to pay for it by the lack of determinism of resource release.
When studying different programming languages, you can try to remember exactly how automatic memory management is implemented in each of them, but after studying several languages, it will be more efficient to generalize this knowledge and reuse it. Of course, each platform or programming language has its own characteristics, but knowledge of the basic mechanisms of memory management will significantly reduce the learning curve, because only differences will need to be understood and remembered, not the whole mechanism. That is why “pragmatists” Dave Thomas and Andy Hunt in their book
“The Programmer-Pragmatist. The path from the apprentice to the master " advised to learn one programming language each year and get acquainted with other platforms and operating systems. Such a broadening of horizons will allow a wider view of new tasks, as well as allow generalizing and structuring existing knowledge.
Conclusion

No matter how many “new” technologies would come out, no matter how many new levels of abstraction would be invented, knowledge of the “fundamentals” would always be useful. It is much easier to understand several fundamental principles, instead of learning hundreds of seemingly unrelated facts. Knowledge of low-level concepts can be reused, which will significantly reduce the time to study "new technologies", because for the most part, they are not. In addition, sooner or later
“abstractions will be allowed to flow” and in order to eliminate it, you will have to understand how it is arranged inside.