Design Patterns and Frameworks

1. Introduction:

Design Patterns is the paradigm constantly discussed, not only by people trying to apply them as solutions to the programming problems they face but also by those, who are their eager opponents. No wonders a few other SAPM blog posts were devoted to that topic. And yet, I think I have some additional information I could share about them.

2. Summary:

This article introduces unfamiliar reader to the software Design Patterns and the advantages, as well as problems that they may relate to, when big projects are concerned. I also stated reasons, why in my opinion some of the flaws of Design Patterns may be solved with use of Software Frameworks, and how they help their users to comprehend Pattern Paradigm. In the last part, I shortly presented the Qt/C++ programming framework and described how some basic design patterns were used in its architecture and what implications it has on the client code of that library.

3. Background:

Design patterns are the solutions to reoccurring software design problems that engineers are facing in their projects. These are the techniques that have proven themselves in many different contexts and help to write code that is much more reusable. They are recorded in various catalogs (e.g. [1], [2]) along with the description of context they are supposed to be used and list of advantages and consequences of their applications. There are many benefits drawn from knowing and using design patterns [3]:

  • they can reduce development time as these solutions are given and widely used;
  • solutions are tested in a number of implementations, thus the design based on them is very robust;
  • they are very important in a large-scale projects, since they enhance documentation and facilitate communication among team members.

Apart from these, also inexperienced programmers may benefit from reading the patterns by developing good design skills and being prevented from “reinventing the wheel”.

Although all the good that design patterns bring, there are potential pitfalls of using them. Among the problem are steep learning curve, temptation of their abusement ([4]) by novice programmers or additional effort in design modification in order to take them into account. Also, they are not a piece of code that can be just used in an application being developed, but the abstractions that yet are to be implemented. What is more, as stated in a lecture – they may be an indicator of a “language smell” [5], the development language missing some features. And Design Patterns add to the code duplication! So what can we do then? Are these a real problems? In my opinion design patterns are the right tool to be exploited in software projects, especially large ones. However, I also think that some of the aforementioned drawbacks may be easily overcome with use of appropriate software frameworks which incorporate ideas of Design Patterns themselves.

4. Frameworks:

“A framework is a reusable design of all or part of a system that is represented by a set of abstract classes and the way their instances interact” [6]. It is a form of design reuse, provided by third parties in order to facilitate application development. Physically, it is a set of modules or libraries that extend functionality of used language. To be reusable, it usually implements design patterns and forces developer to think in terms of these paradigms. If a programming team uses this kind of framework, many issues of the design patterns are getting solved by themselves.

Firstly, I need to defend the programming languages capabilities. If the framework may be used in a given language, it means it intrinsically supports possibility of being facilitated with reusable solution. Thus, they are not susceptible to the “language smell” phenomenon. This is a case, for instance with a C++ language. C++ is said to be much more difficult than Java, which has much more design patterns already embedded. However when used with e.g. Qt ([7]) framework, it gets the same easiness of use. It could get even more useful than other languages if the framework is especially designed for a problem that application is to solve – for instance communication applications will benefit much more from patterns  used in ACE ([8]).

Additionally, when using frameworks, it is much easier for developer to write bug free and higher quality code. It so, since they only have to focus on development of concrete solutions instead of abstractions and application internal skeletons. Not to be forgotten, the most popular frameworks tend to be used by thousands of people, thus it’s highly probable their bugs has been already spotted and fixed.

Thirdly, using established frameworks, help to get the use of design patterns right. The frameworks themselves tend to be documented well, which results in developers having better understanding on what is going on. Also, they have to implement client code only. That means, they are freed from making some of the design decisions and are forced by the framework to structure their components correctly.

Last but not least, open source frameworks give great opportunity to learn how to implement design patterns correctly in a real world. Even though such implementations are provided in the design patterns catalogs (e.g. [2]), they are considered there in isolation to everything else. In life, we sometimes have to trade single responsibility rule or take into account some other external factors. The source code of such programs is the best way to see, how top developers deal with such issues. This is one of the reasons, why I want to present the reader to the Qt Framework.

5. Qt Framework and its Design Patterns:

Qt Project [7] is a cross platform framework originally designed for C++ developers, which eventually supported also CSS(-like), QML and JavaScript languages. The project is constantly being developed and maintained for more than 18. Although at the beginning it was significantly refactored few time, the current release is rather stable. It is a mature and very well engineered project, which follows many of the established design patterns (more than 20, [15]). Of course, the library not only exposes the patterns to the client code, but extensively uses them by itself. This gives a proof by itself for how crucial design patterns to the solid design are. I suppose that quick overview over the design patterns used in Qt may be beneficial for some readers and get them engaged and encouraged to explore the topic in more detail on their own.

5.1 Strategy Pattern:

One of the exemplary usages of the strategy pattern (algorithm encapsulated into an object) in Qt is QValidator. This is an abstract class, that provides validation of the text input with QValidator::validate(…) method (also enables fixation of input, to make class more general with QValidator::fixup(…)). The context object (be it a line edit, a spin box or other), which uses the validator depends on its interface and for every input change, checks if it’s valid and takes appropriate action (e.g. if the integer value is expected, however  arbitrary text is given, its background goes red). If there is no appropriate validator available to meet ones demands, they have to inherit QValidator and overwrite its two abstract methods.

Fig. 1. QLinedEdit with QValidators class diagram.

The solution is really nice, since the validation code may be reused in every class that requires textual input. And it is much more compact than either creating subclasses of QLineEdit (and each input widget) that validate input or registering validation object on text change events (as is done e.g. in Java Swing library).

5.2 Lightweight with Proxy:

Some of the Qt classes (like QVector, QList, QMap or QDomNode) implement Proxy pattern. It means, they don’t contain explicitly the data that they are supposed to have (e.g. array of stored elements in vector). Instead they consist of a pointer to a shared data block that contains a reference count and the data. The classes take care of housekeeping such as modifying the counter depending on how many classes have access to the data. Copying of data occures lazily (so called copy-on-write), when one of the instances is about to modify it. Such approach has few benefits over the traditional explicitly shared data. First of all, the objects are lightweight and making their copies is fast because it only involves copying the counter. Secondly, if most of them is used in read-only mode, no additional memory is to be used, no matter how many copies are done (apart from the memory for pointers). It also saves programmers from choices if they should pass and return instances by reference or value (with unnoticeable performance penalty).
If it comes to the programmer, he doesn’t have to be aware of the copy nuances. However, if he also wants to have such a behaviour in his own classes, Qt encourages him to do so by inheriting the QSharedData and referencing it with QSharedDataPointer or QExplicitlySharedDataPointer.
When discussing the Proxy pattern, it’s worth noticing Qt has its own smart pointer classes, which may help handling pointer. Among those there are QPointer (which is a guarded pointer), QSharedPointer (reference counting pointer), QWeakPointer (automatic weak reference to the pointer). Using smart pointer classes prevent from memory leaks and handling dangling pointers.

5.3 Observer pattern:

One of the big advantages of Qt over the other C++ frameworks is easiness of realising communication between objects (inherted from QObjects) – their signals and slots mechanism. The mechanism allows for type-safety and loose coupling between the callee and caller, unlike in standard callback scenario. It is realised with additional meta-data structure added to objects at the compilation time. However at the end, everything comes down to the Observer pattern.

5.4 Composite and Template Method:

Like in many other GUI frameworks, Qt utilizes Composite Design Pattern to display its widgets (QWidget inherited classes) and handle user input events. The widgets are arranged in hierarchical structure (parent-children relationship), which reflects their z-order (depth on the screen).

Composite class diagram in case of QWidgets.
Fig. 2. Composite class diagram in case of QWidgets.

As may be seen in the Fig. 2 presenting a class diagram, Qt Composite is a slightly different than the traditional one. There is no distinction between Leaf and Composite. It is because all the QWidgets are allowed to add children at any time.

When the screen is to be redrawn, appropriate event (QEvent) is sent the parent and its QWidget::paintEvent(…) method (Template Method) invoked. Then the event is propagated down to the children.

When the mouse click event (or any other user input event) is concerned, it’s first dispatched to the top-most children and appropriate QWidget::mouse*Event(…) method invoked. If it’s handled by the method (QEvent::accept()), no further actions are taken. Otherwise, the event is propagated up towards the parent, on each hierarchy level calling widgets that might be interested in it (click occurred in their bounding rectangle).

Fig. 3. Example scenario of click event.

Fig. 4. Object diagram for example setup.

Fig. 5. Sequence diagram for a given scenario.

To visualize theses steps, let’s assume scenario of generation of mouse click event, as in the Fig. 3. Keep notice, the button is disabled, thus it will not be interested in the event. Object diagram for this setup is presented in Fig. 4. Simplified sequence diagram for scenario of message dispatching shows Fig. 4. First, qApp sends event method to the button. It doesn’t accepts the event, thus qApp tries its parent, which is QTabWidget tab.

6. Summary:

In my opinion, Design Patterns are very useful paradigm. They are a set of tools, which if used wisely may pay-off, especially when large programming projects are concerned. Undeniably, many inexperienced software developers may find them to be a great source of knowledge, to improve their design skills. However, they are no silver bullet and may be over- or misused leading to degradation of a project. Software engineers need to be careful when applying them – that means they have to consider all the advantages and trade-offs that pattern catalog mentions about them. This is a skill, which still requires an experience. However, if developer has possibility to use programming frameworks as Qt (or ACE, .NET, Java), it is much easier for him to make design decisions and start journey with design patterns.

6. Bibliography:

[1] Gregor Hohpe and Bobby Woolf. 2003. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA.
[2] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA.
[3] Marshall P. Cline. 1996. The pros and cons of adopting and applying design patterns in the real world. Commun. ACM 39, 10 (October 1996), 47-49. DOI=10.1145/236156.236167
[4] Design patterns – do you use them?,
[5] Design Patterns Are Missing Language Features,
[6] Frameworks=(Components+Patterns),
[7] Qt Framework,
[8] ACE Framework,
[9] Discover the Design Patterns You’re Already Using in the .NET Framework,
[12] C++/Qt Design Patterns,
[14] Alan Ezust and Paul Ezust. 2006. An Introduction to Design Patterns in C++ with Qt 4 (Bruce Perens Open Source). Prentice Hall PTR, Upper Saddle River, NJ, USA.
[15] Design Patterns in Qt 4, video,

Resp: “Why Pair Programming Is The Best Development Practice”

1. Introduction:

Reading an article “Why Pair Programming Is The Best Development Practice” written by User s1369981 I was struck by the arguments for incorporating pair programming into the software development process. Moreover, since the Author sounds very convincing and is into that programming technique, he passes on the enthusiasm. Even though there are already other responses that contradicts his statements, I think he is right… at least partially.

2. Summary:

In the first part of this document, I take an attitude towards Author’s ideas about difficulties and benefits of Pair Programming process. I present some of my views on both issues and then generalize article’s punch-line with claim that Code Review practices are the ones that should be used in any software development project. Then I present some facts supporting my reasoning and propose the way how to start performing most basic Code Review variant, namely Peer Review.

3. Thoughts on article:

In the article, Author first starts with information there are many voices saying Pair Programming is bad and doesn’t work for them. Then he claims that the bad experience with this approach stems mostly from the fact it was not executed in a correct way and gives the rules that people should follow.

I haven’t done pair programming before, so cannot speak for myself. However, it isn’t surprising there is much more to it than just not following rules – a human factor. Having read linked resources such as [9], [2] and other industrial research [3] it seems the biggest problems in practicing Pair Programming are:

– individualism, which cannot be neglected, since programming is seen by many developers as a personal thing;
– scheduling – to realize Pair Programming, developers have to work within same hours and synchronize their days off, which influences their flexibility;
– difficulties to find appropriate partner, so that they would work flawlessly and be compatible in their knowledge (apart from knowledge sharing case, people find Pair Programming fine if they work with programmer of complementary skills, who is smart and knowledgeable or easy going in terms of communication).

In my opinion, given problems cannot be solved with general guidelines. In fact, their importance is dependent on the team, how cohesive it is, how people recognize each other (as knowledgeable, smart, liked, etc.) and how the members get along with each other. If these obstacles are the minor ones, pair programming could work well. Otherwise, it is something that probably fails giving negative results as observed in some teams in [4] study.

The other part of the article discusses benefits of conducting Pair Programming. The biggest one mentioned is the fun that it gives to participants and helps overcome the boredom that arises while working. Another main benefits given are pretty straightforward. I point them out deliberately:

– many defects and bugs are caught before even introduced, which is a great advantage, and spares the time for bug-fixing and maintenance,
– the knowledge is shared among programmers, what helps improving a team as a whole, thus increasing quality of later code they produce;
– design and code quality is improved, due to the immediate brainstorming, discussion and “fear” of embarrassment.

So, since Pair Programming has such huge pros (especially fun), Author finishes his work with conclusion that it is the best development practice.

First of all, I don’t agree that the programming at company becomes boring. It’s always challenging, otherwise we would be reusing the same code and companies didn’t employ more and more software engineers. There could be some issues, when we are only delegated to code maintenance and bug-fixing. People generally are not satisfied with their work, if no results are visible. When the bug is removed there is probably nobody to praise you. They say that error shouldn’t be there from the beginning. Refactoring… fine, but who notices apart from the team, who gives you credeits? Maybe based on those LOC statistics… In this case I can get Author’s point.

And coming back to pair programming, it could be fun for people who are opened for cooperation, problably as the Author is. There are however humans, who find it very distracting [9] or psychically fatiguing [5] to work so closely with others for such a long time.

4. To do or not to do?:

I don’t think that Pair Programming should be always chosen. As stated earlier, it could work for you or not, what depends on the spirit of your team. You have to consider all pros and cons, which basically comes down to evaluating the eagerness of your team mates and convincing the management level (answer their question: why to pay for two programmers doing one thing, when we could hire outstanding one for such salary?). Take the problem really seriously, since there is a long adaptation period (could be few months, [2]), until this approach pays off. If the wrong decision was made, these are the months you lost on bad performance and maybe some smell stays behind due to programmers misunderstandings and arguments.

5. What is left then?:

But what is there, if you find that  Pair Programming is not a solution for you? Do you have to throw away all the benefits it provides? The answer is “Of course not!”. Pair Programming is just an extreme of the set of practices that are called Collaborative Techniques (for a very good overview, see [6]). You can choose from others like formal inspection, informal technical reviwes and document reading. Personally, I think that you should pick one of these if not Pair Programming. Everyone can benefit from collaboration, the statement supported by Rubber Duck Debugging [7] method (another extreme, collaborating with virtual peer) and numbers:

“testing alone has limited effectiveness — the average defect detection rate is only 25 percent for unit testing, 35 percent for function testing, and 45 percent for integration testing. In contrast, the average effectiveness of design and code inspections are 55 and 60 percent” [6]

The code inspection is said to be most effective method, but results of other approaches fluctuate around same value. The code reviews methods are used by such giants as IBM, AT&T and many more (if not all successful companies). Remember that finding a bug in the source code is being given on a silver platter. Getting to it in the later stages of process developement, means necessity of tracking it from effects it causes.

6. Getting started with Collaborative Techniques:

Even if your management doesn’t see it necessary to reserve slots for collaboration, I would strongly encourage you to start small – find a “buddy” that does code review with you. You would improve your skills, detect bugs and this is fun – because constructive discussion is fun! And it’s not that difficult to carry out basic code review, if for instance you are using github or bitbucket. Open particular commit of a file, and if you find something worrying, write a comment to the line of concern. The code is not spoiled with anything You write, your peer gets that information and discussion is started. And you both may come up with new ideas. Two heads is better than one. If you still hesitate or have some doubts, have a look at the blog [8].

7. Conclusion:

All in all, I think that Pair Programming is great, however it’s not a silver bullet that should be used by everyone. It has some alternatives among Collaborative Development Practices, which may even perform better. Your project needs to analyse all pros and cons of every of them and choose the best fit. Your code should be reviewed by others, because this way it will get better.

8. References:

[1] Why Pair Programming Is The Best Development Practice?
[2] A. Cockburn, L. Williams. 2001. “The costs and benefits of pair programming“. In Extreme programming examined, Giancarlo Succi and Michele Marchesi (Eds.). Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA 223-243.
[3] A. Begel, N. Nagappan. 2008. “Pair programming: what’s in it for me?“. In Proceedings of the Second ACM-IEEE international symposium on Empirical software engineering and measurement (ESEM ’08). ACM, New York, NY, USA, 120-128.
[4] H. Hulkko, Abrahamsson, P., “A multiple case study on the impact of pair programming on product quality“, Proceed-ings of International Conference on Software Engineering, pp. 495 – 504, 2005.
[5] Pair Programming vs. Code Reviews,
[6] S. McConnell. 1993. “Code Complete: A Practical Handbook of Software Construction.” Microsoft Press, Redmond, WA, USA.
[7] Rubber duck debugging,
[8] Simple way to do code review,
[9] Pair Programming – My Personal Nightmare,

Why don’t we use Continuous Integration?

1. Introduction:

While reading some articles or blog posts ([1], [2], [3]) on Continuous Integration it’s easy to come to the conclusion that this approach ensures your code quality, reduces risks and sets programmers minds at ease. It is not dependant on any particular software development methodology. If it is so, I thought that everybody should use it for the projects they carry out. However, it is not a case – there are many companies that still haven’t started development with CI and I question myself “why?”. This article aims to answer that question.

2. Continuous Integration itself:

Continuous Integration [1] is a software development practice which assumes constant integration of code under development. Developers check-ins to the integration server should be made few times a day. Process of code submission is not done until entire compilation, tests and inspection is carried out, proving no problems. Otherwise instant measures should be taken by the developer, to fix any issues. Most important outcome is that there is a great probability that software is functional and the newest version is available to whoever wants it.

3. Background:

Some of the issues that I raise in this article are backed up with examples taken from my experience in a company I worked for. Therefore a brief introduction to it is necessary. The firm is a small start-up project, which manufactures home automation system devices. The software developed there is to be considered as long-term projects and large when compared to the number of people working on them. Main software developed there is:

  • low level programs for field devices (sensors and actuators);
  • applications for controllers running embedded (mainly Linux) operating systems or for mobile devices. This software was the biggest one, constantly extended with newer modules;
  • installation configuration system for Desktop computers.

When I joined that company, there was only one experienced programmer working for it. After some time, he left leaving me as the only permanent one, with others being partially hired for some tasks, when there was a need for that. Don’t take the impression of the company, as working in terms of anti-patterns – I mention here its bad aspects only, since the article requires so. I believe there are many companies like this one, especially small ones, that work the same way.

4. Why CI has not been implemented yet:

Although many of its advantages, CI doesn’t make its way to all the projects being developed. Most people seem to know its advantages and the outcome it gives to the project. It sounds like a panacea to many of the issues concerning software development – it enforces programming good practices and forces developers to be consequent. However, many aspects such as human state of mind of both managers and programmers, developers’ habits and abilities or the company targets (e.g. money first, quality later) stop CI from being the part of their projects.

4.1. Commits frequency:

First of all, I find that basic assumption of CI could be problematic in some circumstances – very frequent code check-outs. To realize it, programmer commits are to be small what poses a difficulty of dividing work into really tiny chunks [2]. Even though developers tend to modularize and divide their work into manageable pieces, it’s often hard to have such granularity of modifications that each is ready in few hours. Every feature being developed requires full life-cycle consisting of consideration, planning and implementation. Especially, if the feature is to be tested before check-in, it’s problematic to reduce its development time.

Moreover, incremental committing just doesn’t work sometimes. This could happen, for instance, if software architecture was not well thought. That kind of issue may be even more frequent in Agile development. Let’s say, one needs to modify part of the code, to adapt it to some changed requirements. If multiple modules are dependent on that change, the tests may fail if the modification is not made in its entirety. Thus bigger change is to be made and it could take more time, before the program works again in as a whole. Then, in order not to break the build, the commits may not be just checked into the main repository for even few day, whatever is needed.

The above example may be a little exaggerated but there is even more to it – human mentality. Programmers, who start working on project parts in the beginning of the day, naturally tend to first analyse the problem and after solution is chosen, implement that strategy. That means most of the commits could occur in the end of the day, which makes integration even more troublesome – they have to get into the queue to the integration server and that takes time.

Increasing commits to the high frequency expected by CI requires significant mind shift. Thus, if there is no mentor, who may help in such process (e.g. experienced manager or some senior developer, who has done CI before) this transition may become a barrier not to be crossed.

4.2. Mainline only:

Another aspect, which seems counter-intuitive and may result in turning CI down, is requirement to keep every code in a mainline. This seems even more insane, when CI assumes that broken build gets highest developer’s priority. The problem here is that it is not uncommon that programmers work on some feature in their spare time, between other, more important works. That feature may not be usable or functional for a longer period, and thus incorporating it would very probably break the build.

In my company, there were many projects (mostly extensions to the controlling projects), that were started because there was a need for such functionality. However, there was no need for them to be completely finished or polished (e.g. easily configurable as the rest of the software), because they were meant to be used just in a few instances. Once proof-of-concept was working, there was no additional time devoted for finishing them and making a cohesive part of the entire project. The reason for this was, of course, limitation of resources. If the need occurred, they were meant to be continued, but until then there they had no appropriate tests and they were not acting as a cohesive part of the project. Thus they were held as a separate branches, which according to [1] is against the CI idea.

The main reason why some developed modules should not be on the mainline is lack of resources devoted by managers to it. If it is not finished or tests are not complete, and other duties have higher priority, committing it to the main code is not what CI expects.

4.3. Automate your tests:

Creating automated tests for every part of the project, when introducing CI, may impose another difficulty. As mentioned, automated tests are very important part of the CI process and they should cover the code pretty well to reduce the risk of potential bugs [4]. Even though it’s a common practice to write tests, some of them are very difficult to automate.

In our team we didn’t have people who were specialized in tests. This led to situation that testing of more complex modules like those responsible for configuration generation (writing configuration validation was as very difficult) or some GUI components was very challenging and time consuming. Given limited number of developers and time, some of them were carried out manually or by the group of people who used applications (like beta-testers). In the second case, if some bug was detected, first its harmfulness was estimated and then fix priority set. So the “small” bug might be there left for appropriate time to come, which is again against the CI ideas.

One may argue, that difficulty of automated tests writing is not a point against Continuous Integration. CI may still be used, just with small coverage or no code tested at all. However, in such a case it is not that efficient (only compilation correctness is proved) and convincing the manager of CI usability is much more difficult. So, when decision about taking the track of CI is to be made, there are less advantages to speak out.

4.4. Appropriate timing:

One important aspect that should be addressed is the time in the project lice cycle, when CI is to be introduced. It is much easier to have the project running with CI, if it was started with CI in mind. Then, all the components of the project (such as tests, scripts, even its architecture) are prepared so that it’s compatible with the idea and tools used for CI.

It is not easy, though, if the project is already ongoing (this could be the case of long-term projects). In this case it could require too significant modifications or time-consuming additions to be made, to consider CI as a good solution (of course this approach is short-sighted). In such situations, it should be estimated, what are the advantages and costs of switching to CI – the latter ones could be too high, so even if there is a team will, managers don’t agree.

4.5. Direct costs:

Not to be forgotten obstacle of introducing CI in the company may be the cost of integration servers and time cost, required to run these machines [5]. There are many open source projects such as Cruise Control [6] that could be used for that purpose. However, there is still the need for some training (especially, when no one in the team has done that before). The hardware cost depends on the type of project being tested. If it’s small and tests are not resources consuming, some old computer may be used [7]. Otherwise, newer machine should be used. In cases of more complicated processes, where build time exceeds 10 minutes limit [1], the build should be divided into few steps over multiple computers. Again, this may pose significant costs, especially for smaller companies. Larger ones, probably won’t see that as a drawback, since in comparison to money they pay as salary to the software engineers is much more insignificant cost.

4.6. Project ROI:

Last thing, not connected to large projects, but worth mentioning while CI is discussed is return of investment [5]. In case of small programs with short life cycle period, especially for those that long term maintenance is not assumed, the burden of setting things up could be too high.

5. Summary:

In my opinion, presented issues are the most important ones that prevent software developer teams from  introducing Continuous Integration. It is worth for a team considering using CI to detect if these apply to them. If so, they should not be discouraged but try more step-by-step approach. Continuous Integration has significant advantages which are especially obvious for projects where more than one developer work on. It is worth the effort in a longer run, since it reduces integration risks, gives better overview of the project state, encourage developers to work proactively and not to procrastinate. It is a really good way to achieve high quality product just by sticking to some general rules.

6. Bibliography:

[2] (also 2nd and 3rd parts);
[3] Paul Duvall, Stephen M. Matyas, and Andrew Glover. 2007. Continuous Integration: Improving Software Quality and Reducing Risk (The Addison-Wesley Signature Series). Addison-Wesley Professional