Mastering Angular Components
上QQ阅读APP看书,第一时间看更新

Components, invented by nature

Components, embracing encapsulation, and composition are an effective way to build maintainable applications. Composed from components, applications are very resistant to the negative implications of change, and change is a necessary thing that will happen to every application. It's only a matter of time until your design will be challenged by the effects of change; therefore, it's very important to write code that can handle change as smoothly as possible.

Nature is the best teacher. Almost all the achievements in technological developments have their origin in observations of how nature solves problems. If we look at evolution, it's an ongoing redesign of matter by adapting to outer forces and constraints. Nature solves this by constant change using mutation and natural selection.

If we project the concept of evolution onto developing an application, we can say that nature does actually refactor its code in every single moment. This is actually the dream of every product manager—an application that can undergo constant change but does not lose any of its efficiency.

I believe that there are two key concepts that play a major role in nature that allows it to apply constant change in its design without losing much efficiency. This uses encapsulation and composition. Coming back to the example of our bodies, we can actually tell that our organs use a very clear encapsulation. They use membranes to create isolation, veins to transport nutrition, and synapses to send messages. Also, they have interdependencies, and they communicate using electrical and chemical messages. Most obviously, they form larger systems, which is the core concept of composition.

Of course, there are many other factors, and I'm not a professor in biology. However, I think it's a fascinating thing to see that we have learned to organize our code very similarly to how nature organizes matter.

The idea of creating reusable UI components is quite old, and it was implemented in various languages and frameworks. One of the earliest systems that used UI components was probably the Xerox Alto system back in the 1970s. It used reusable UI components that allowed developers to create an application by composing them on a screen where users could interact with them:

The user interface of file manager on the Xerox Alto system from the 1970s

Early frontend UI frameworks, such as DHTMLX, Ext JS, or jQuery UI implemented components in a more limited fashion that didn't provide great flexibility or extensibility. Most of these frameworks just provided widget libraries. The problem with UI widgets is that they mostly don't embrace the pattern of composition enough. You can arrange widgets on a page and they provide encapsulation, but with most toolkits, you can't create larger components by nesting them inside each other. Some toolkits solve this by providing a special kind of widget which was mostly called a container. However, this is not the same as a full-fledged component tree that allows you to create systems within systems. Containers were actually meant to provide a visual layout container rather than a composite container to form a larger system.

Usually, when working with widgets on a page of our application, we'd have a large controller that controls all these widgets, user input, and states. However, we are left with two levels of composition, and there's no way that we can structure our code more granularly. There is the page and there are the widgets. Having a bunch of UI widgets is simply not enough, and we are almost back to the state where we create pages plastered with form elements.

I've been a user of JavaServer Faces for years, and besides all its problems, the concept of having reusable custom elements was groundbreaking. Using XHTML, one could write so-called composite components that consisted of other composite components or native HTML elements. A developer could gain a fantastic level of reusability using composition. In my view, the big issue with this technology was that it did not address the concerns in the frontend enough to become really usable for complex user interactions. In fact, a framework like this should live completely within the frontend.