#begin

 

Juli 1th, I finally finished reading the Object-Oriented Software Engineering, A Use Case Driven Approach book. I read it front to back, although I have to admit I only read parts of the second case study: Telecom chapter, because there was another case study explained in the book.

I will write a review of the book soon but since it’s such a massive tome, I will review some of the chapters individually. Today I want to zoom in on the chapter (11) about Components. I really enjoyed reading this chapter since I’m a sucker for component / plugin based architectures. This is not exactly what’s described in this chapter because it speaks more of software reuse than plugins but there are some real gems here. Let’s take a look:

 

Components

So the soul purpose of this chapter is to encourage software reuse in object oriented software engineering (OOSE). This will greatly speed up the development process and improve the quality thereof. To optimally reuse software it should be packaged in such a way that it is easy to use, learn, distribute and implement. The way to do this is through the use of components. But what are components and what is their purpose? Well, a very nice description is given in the book:

When working with software components, we should view these as a part of the programming language. Just as we have primitive constructs in the language, we will have primitives at a higher level of abstraction. In this way components constitute a reinforcement mechanism for the implementation language; instead of working with primitive constructs, we will work with constructs of higher level abstractions like lists and windows. In this manner we can thus leverage the development from primitive constructs to more complex constructs.

When you read this you probably thought; I write software this way… what’s special about this? Well the fact that this book was written in 1991! There was no such thing as GitHub or GitLab back then. What I do find really intriguing is the notion of viewing components constructs as ‘higher level programming constructs’. I think we all do this in the current day and age. We communicate to other dev’s in far more complex concepts than strings and integers.

The concept of components is not unique to software engineering, but is found in many other forms of engineering as well. Electrical engineers often (read always) work with components, mechanical engineers have standardized bolts and other materials and even chemical engineers have standardized solvents and process devices.

The book mentions another interesting bit: “Many feel that components are one of the most important solutions to the software crisis”. Software crisis means the never ending demand for software in this context. I think they got this prediction pretty close to reality although software development 30 years later (remember the book was written in 1991) is a lot more than just weaving components together. Software has gotten so much more complex which is not easily expressed in a manner of components. There is still a lot of really domain specific, custom software being created that requires domain and subject matter expects to help because there are no components for this and probably never will be. Yet, components define the way we work now, think about all the frameworks, libraries and cloud services we use day to day. I don’t think any sane software developer, startup or company would start to develop everything from scratch (it depends on your company of course; if you want to compete with let’s say Unity3D, you would want to create a game engine form scratch, but probably using many commonly used libraries, frameworks and other components).

So in order to really industrialize software development we need components. And that is what we can see today. But let’s step back to 1991 and see why there weren’t any components available.

 

Why do we not have components today — in 1991?

I thought it would be interesting to include this section of the chapter since I think it is nice to see how the software industry has changed over the past 30 years. There are 6 answers identified to the question of why there are no components today.

  1. Projects are often done on a tight budget and time schedule. This hasn’t changed a bit haha. Designing components takes time, and making sure they are maintainable, documented and tested takes even more time. Components ought to be of higher quality than ‘normal’ software since they need to be used in many different contexts and projects. Making sure code is properly separated into independent components requires more effort and therefor more time and money. Components are more costly to develop than normal software and since it is not profitable to make components for a single project, there is no real incentive to do so.
  2. It is safer to write the code myself, than to use some other fella’s code. There needs to be a certain level of trust on the author(s) of some component. If there is going to be faults in the code, I want to be sure they are fixed fast and maybe even change the code myself. This issue still persists today; when I look for components or libraries to use I make sure they are of high quality and check the issue board and activity in Git(hub/lab) to make sure the project is not abandoned.
  3. There is no recognized standards for components; I think the industry solved this part. We all use projects straight from GIT in our own. We use Nuget, Maven/Gradle packages, NPM packages and others. We have nice package manager software that even makes sure the correct dependencies are pulled in when integrating a package into one of our projects.
  4. Existing components cannot be found. This have changed as well with the advent of package managers. They pull in dependencies automatically and finding components is fairly easy of Git or other dedicated websites to search for packages.
  5. People feel productive while writing source code, you feel progression when you do so. When you use other components, you will write less source code and thus might feel less productive. The book even mentions that “lines of code” is the most common metric for software developers. This opinion has changed drastically over the past 30 years I think. Productivity is not measured by lines of code, at least not anymore.
  6. There is no components market. Yes, I think we nailed this one. There are so many places to find and download components like github/lab, maven/gradle, npm and even some proprietary ones like the Unity AssetStore.

 

What’s a component?

The book then goes on explaining what a component actually is. A nice definition I found in this: “A component is a standard building unit in an organization that is used to develop programs”. Where a complex component that is easy to use raises the abstraction level of the code and forms a simplification of what is implemented. This also means; a component must be designed aimed toward reuse! A component should capture all operations that make it meaningful and useful to use for any developer and no other operations. Since components must be reusable, they must be of great quality. Components with bad reputations will never be used! They must be tested, efficient and documented and therefore are much more expensive to develop that “normal” software.

The public interface of components must be well-designed and easy to understand with correct documentation. Packaging must also be done is such a way that is promotes reusability.

When you design a component there are two schools of thought: One, they should be flexible which means they can easily be adapted and changed to support your individual needs. Two, they are already specialized and you shouldn’t make changes to them.

It is important keep these two things in the back of your mind when developing components. You should not make components that satisfy both concepts since I might quickly become to complex.

The book then goes on how one might identify components in existing systems. For example; objects that form some sort of inheritance tree could be a component, of UI that is commonly used and independent can transition to a component. Even control objects that serve common functions could make up a component, think of a Stack of a Queue.

 

Implementing with components

Next there is a section about how you would work with components; Up till now the book has only discussed how to implement code through the concept of a Block. In OOSE a block is a named piece functionality which I will explain in the full review of this book. I won’t go into it in detail now, but stay tuned!

A nice piece in this section is that for OOP inheritance is viewed fundamental for reuse since you can inherit and thus reuse things. This is a misconception, inheritance is not a prerequisite for reuse! It is possible to make reusable code without inheritance! Acquaintance (uses) relations between objects can also be used for making code reusable. However it might not be obvious when to use acquaintance over inheritance.

An important first rule when implementing components is to first use composition with components. There is a common need that you must adapt the system. There should be no need to adapt the component in order to implement it! You should encapsulate the component in another object that acts as an interface between the application and the component. This is also a great technique to make the application independent of the component implementation like the programming language used. Yet, you must also make sure that your encapsulation technique does not create to much overhead to avoid efficiency losses.

 

Component management

In the current day and age we all use nice package managers that take care of our component downloads, dependencies, updates and even sound notifications to us when there are updates available. I bet this is music to the authors’ ears when it comes to component management. However there are also many issues with these package managers. I think, in JavaScript land on NPM, package dependencies are notoriously bad. I’ve seen many packages that pull in so many dependencies you wonder why it needs them. I also remember there are NPM packages (components) that just return true and false. I hope this is a joke (although downloads are recent), because this is nonsense.

The book explains that a component system is not profitable for only one project. By this they mean that making in-house components for just one system is not going to give you a boost in productivity and budget. The real benefit comes when components could be used in multiple projects, and therefore component management should be focused on multiple projects. It’s also necessary to create come sort of component management group who oversees the creation, development and maintenance of those components.

Components often evolve naturally from source code. If classes can be used in multiple projects they should become components, and thus they might require some extra work to refine them more. These activities are on the developers themselves, they will recognize the component in the code and should put some extra design into it to make it more fitting in the component structure of the company.

 

Component construction

There are a couple of things that are of importance when creating components. Reuse does not come as a side effect, it must be designed for. As well as specification, construction, testing and documentation must be done. This makes components more expensive to develop than normal software. The book mentions it might even be 10x more expensive! I think this is pretty valid; sometimes the cost of making something generic and robust, refactor it out into it’s own components and reintegrating it back into the project takes a lot of time.

The book suggests some criteria what makes a good component:

  • Understandability: A component will probably represent some abstraction. It must have high cohesion and only offer the operations that are logical for that abstraction, and nothing more. It must have a well-defined interface, syntactically and semantically. The authors mention something interesting as well in this part which is: “If two operations in two different components have the same name, they shall act in a similar manner”. I think we often see this today, especially when you have some sort of component architecture where, in order to hook the component into the system it needs to implement certain functions, which share the same name and act in a similar manner.
  • Independency: A component should be as independent as possible of surrounding entities. It should be loosely coupled to the rest!
  • Generality: A component should offer general abstractions which makes it applicable in multiple applications without having to undergo changes. It’s standardized in regard to naming, exception-handling, structure and so forth.

The book also mentions four criteria for good and reusable components:

  1. Reduce the number of parameters to functions as much as you can, this will improve the understandability of the component.
  2. Avoid using options in parameters. Options should be set at creation of the class or procedure. Special methods should be available to change these options.
  3. Avoid providing direct access to instance variables! Use getters and setters in case of OO languages for example, this will free the implementation from the actual interface.
  4. Use consistent naming of functions and variables. This also goes to length for multiple components.

 

The component system and documentation

Next the authors start to describe the process of how the “component management team” should operate. A process is described how to propose, construct, distribute, use and delete components. I will not go to deeply into detail on this part since I think many people have this figured out. The same goes for documentation. I do want to mention some interesting tidbits I highlighted in this section like:

It is important not to be passive in the search for components. Just by waiting, components will not be proposed. Developers should recognize the generality in some parts of the code and propose to create a component out of it. Also, components should be profitable for the organization. I think this is common sense, but I think every developer has written components, that have only been used in a single project and thus the time and effort was wasted. I think this falls into over-engineering and the concept of YAGNI. Also note that many proposals for components will not be accepted (by the component management team).

There are a couple of metrics to keep in the back of your mind when creating components. The book mentions three of them:

  1. Size: Size effects both the reuse cost and the quality of the component. A component to small will not exceed the cost of managing it and a component to large will be hard to manage and costs might skyrocket.
  2. Complexity: This goes in the same way as size; if a component is too trivial, the cost of managing it is higher than its benefits, yet a complex component is hard to maintain and thus is more expensive.
  3. Reuse frequency: The number of places where the component is used is of importance too. If it’s not, or not frequently used it might be better to abandon it.

They even go into how to document components. They describe two ways of doing this. One of them is through a hierarchical structure, and another is keyword based. Currently there are many great tools to help you write documentation, create wiki’s and generate API reference sheets like doxygen or swagger.

 

Conclusion

This chapter was very fun to read. Personally I found it funny to read about the component management, distribution and implementation/integration. So much has changed with Git, package managers and the open source community. It’s hard to anticipate that 30 years ago I think. Working with components comes so naturally to us now. However, this is not exactly what they aim for with this chapter.

Their aim here is to create and maintain an in-house component library which can be used in multiple projects developed by the same company. They describe the effort that goes into making privately owned components and management thereof. This is a fundamental aspect object oriented engineering, or software development in general! In order to really industrialize software development, we need components.

I think, the industry has aligned itself with that statement over the past 30 years. It will be interesting to see what the future for components holds. Especially with all these services hosted in the cloud. You don’t even need to have the source code of these components, but just send some (HTTP) request and get your results back.

Next I will review another chapter which is of great interest to me: Testing.

 

#end

01010010 01110101 01100010 01100101 01101110

Hey, sorry to bother you but you can subscribe to my blog here.

Never miss a blog post!

You have Successfully Subscribed!