Saturday, 22 September 2012

The Singleton Pattern in .NET - If you can avoid it

NOTE: This pattern is now considered by many (included the creators) an anti pattern and it is presented only for completeness! Read why.

The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.

A Singleton is a class that manages a single instance of itself and prevent any other class from creating a new instance on its own. The only way to get the instance is passing through the Singleton class itself. 

Singletons are frequently used to provide a global access point for some service.

Let's see an example of Singleton that implement a trivial logging service.


and an example of usage:

OK but... what are the advantages?

As we said in the definition of the pattern, the main advantages are:
  • Making sure that there is a single instance of the service. This is accomplished making the constructor private and the class sealed.
  • Providing a global point of access to that instance.

Mmm but I can solve the same problem writing the following code, right?

It is true!

However, there are still some advantages in using the Singleton approach:
  • You don't have to put the static keyword everywhere
  • You can use singletons as parameters or objects
  • You can implement singleton with interfaces
  • You can write tests even if this is not simple
Anyway, singletons have more problems than benefits and these days many developers tend to avoid it if they can.

The biggest problem is the fact that you can use singletons where you want (they are like global variables) and dependencies are hidden inside the client objects. This means that the interface of the client objects don't reveals all the dependencies and this make testing very hard. In addition, in order to be able to write the tests you have to create a mechanism to replace singletons with mocks (a static Initialize method for example) that in some way violates the definition of singleton itself.

These days there are better ways to solve this problem and they usually involve other patterns like Service Locator and Dependency Injection. I will describe these patterns in later posts.

Thursday, 20 September 2012

Abstract Factory Pattern in .NET

The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.

In a previous post, I have shown that in the Factory Method Pattern the object creation is done through inheritance. Instead, the Abstract Factory use object composition. Object creation is implemented in methods exposed in the factory interface.

Wait a moment please... you are going too quick!
What is the advantage? Can you show an example?

The advantage is the same like other factory patterns, that is, decoupling clients from any of the specifics of the concrete classes. They all promote loose coupling by reducing the dependency of your application on concrete classes. Abstract factory in addition allows you to group together a set of related classes and provides a consistent usage to clients. It is a kind of evolution of the Factory Method pattern.

Let's see an example.

Instead of starting from the implementation, I would like to start from the client. I believe that it is easier to understand the value of the pattern in this way. 

We want to provide security services (signing and ciphering), in an application and we want the ability to easily change the level of security provided. 

Look carefully at the client code.



As you can see, the client always rely on abstractions. AbstractSecurityFactory is used by the client to get a pair of related objects: the signer and the cypher. However, the client is completely unaware of the specific classes involved. 

The specific factory (that defines the level of security) is usually defined in some configuration and the GetSecurityFactoryFromConfiguration method simulate this.  

In the example, we are using a normal security level in our application. 

How can I change the security level of my client application?

Simply change the concrete factory! All the other client code remains the same.

Here, we disable the security in the application:


OK, let jump in the implementation.

Let's start with our abstractions:


There is an additional abstraction that is used for convenience in the internals. 


This is the family of classes that represents the absence of security.


This is the family of classes that represents the normal level of security using the algorithms SHA256 for signing and DES for encryption.





I don't want to be tedious and create a set of classes to implement an high level of security. I am sure that you can easily guess it!

You learnt that the abstract factory pattern should be used whenever you have families of products you need to create and you want to make sure your clients created products that belong together.

One of the best example of use of the Abstract Factory Pattern in the .NET Framework is in ADO.NET. There is a class called DbProviderFactory that is an abstract factory and provides clients the ability to create a set of objects designed together to communicate using a specific technology or with a specific database product like ODBC, OleDb, SQL Server and so on.

This is a reduced class diagram that shows some classes involved. 


In this example, the products are all the objects required to communicate with a database: Command, Connection, CommandBuilder, ConnectionStringBuilder, DataAdapter and so on.

Let's have a look of an example of usage of this class.


The beauty of this pattern is that you write the code of your client in a way that is completely independent by the concrete implementation (in this case by the specific database) and this allows you to change the concrete implementation in a very easy way.

Once again, the foundation Object Oriented Design principle related to this pattern is the Dependency Inversion Principle that is worth to remember in the following two definitions.

Depend upon abstractions. Do not depend upon concrete classes.

High-level components should not depend on low-level components; rather, they should both depend on abstractions.

Wednesday, 19 September 2012

Hands-on: Introduction to TDD

Yesterday, I participated to the "Hands-On: Introduction to TDD" event organized by the Cambridge Software Craftsmanship community.

I paired with a C# guy and we tried to apply TDD principles in order to solve a toy problem but after one hour we didn't get too further. After that we had a interesting discussion sharing our feelings about TDD in general, how to approach it and what are the advantages and the disadvantages.

This is a picture taken in the middle of our coding activity :)


This is a summary of what I learnt:

  • TDD is hard and it is difficult to find a master of TDD
  • TDD is impossible to learn using a toy problem
    • What is the simplest but complex enough problem to solve that allows to understand the power of TDD?
  • I have to learn more about ReSharper!
    • My mate was much more quicker than me :)
Regardless of TDD, I believe that the most useful element in order to become a better professional is pair programming. It is extremely useful to see different approaches in solving problems, different ways of working, different tools, different shortcuts and so on. 

I am looking forward to do more pair programming in the future!



Monday, 17 September 2012

Factory Method Pattern in .NET

There is a little bit of confusion around this pattern because Factory Method can be implemented in many different ways but I want to stick with the original definition of the pattern.

The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

This pattern can be used by frameworks to delegate the creation of a specific concrete class at the extern of it in order to provide higher flexibility for their clients. The framework will provide logic using abstract classes or interfaces delegating to clients the responsibility to provide concrete implementations.

Suppose we want to create a very simple framework for a video library that provides a basic system to buy movies. However, because the policies about prices and permissions varies, the framework leave the clients the responsibility to create  the specific policies.

Therefore, the framework defines an abstract class VideoLibrary that implements the buy operation:


As you can see, this class is abstract and the method GetPolicy is a Factory Method. It is responsibility of the client to create a subclass of VideoLibrary and return the appropriate policy. The framework simply define the IPolicy interface and the Customer and Book classes.

Let's write a client that use our video library framework defining the following policies:
  • Children can't buy porn and horror movies
  • Children always have a 50% discount
  • Adults can buy any movies
  • Adults pay the full price
  • A child is a person with age lower then 18
This is the code:




This is an example of usage:


with the relative output:


This patterns provides a way to decouple the implementation of a class (IPolicy) from its use (in VideoLibrary). This is the flexibility that this pattern offers to clients.

The Object Oriented Design principle to keep in mind in this case is the following:

Depend upon abstractions. Do not depend upon concrete classes.

This principle is often called Dependency Inversion Principle.

In our example, the video library framework defines the abstraction IPolicy and does not depends upon concrete implementations. It demands to clients this responsibility and this is accomplished using inheritance.

A different way to describe the principle is:

High-level components should not depend on low-level components; rather, they should both depend on abstractions.

In our example, the high-level component is the VideoLibrary class while the low-level components are the implementations of the IPolicy interface. The IPolicy interface is the abstraction that has been created in order to invert the dependency.




Thursday, 13 September 2012

Decorator Pattern - Streams in .NET

The Decorator pattern allows to attach additional responsibilities to an object dynamically. It is an alternative to subclassing for extending behaviour.

Instead of creating a silly example of usage I decided to rely on one of the best example of implementation that is already available in the .NET Framework: the Streams.

The following class diagram is a restricted view of the Streams hierarchy in .NET:


Recognising the pattern is usually quite simple. When you see an object that inherit from a base class (Stream) and at the same time has a constructor that accept an element of the same base class (Stream), you probably came across to a Decorator.

The idea is that you can create an object that wraps an another object (of the same type) in order to provide new functionalities and the resulting object can be wrapped again creating a chain of objects that together provide a combination of functionalities. The beauty is that any single object is unaware that it is wrapped and this allows to create any combinations of them at runtime. If you consider the alternative of creating a single class for each combination of functionalities, the flexibility you get with the Decorator pattern is immense.

In the previous diagram there are three Decorators:
  • BufferedStream
  • CryptoStream
  • GZipStream
But what about the others classes?

FileStream, MemoryStream, NetworkStream does not have a constructor that takes a Stream. They simply are Components and not Decorators. This means that these objects can only be wrapped and cannot wrap other objects. These objects represent the end of the chain.

Yes, it seems quite complicated but it is not. Let's make a concrete example.

Problem

Create a TCP client that allows you to send a message over the network to a TCP server. Before sending, the message will be buffered, compressed and then ciphered. The server will do the opposite operations in order to receive the message correctly.

Streams represents the best way to implement this scenario.

Solution

This is the code that creates a TCP client and send the message over the network:


From the example, it should be easy to figure out how the wrapping process works. Wrapping is the way to add functionality in a dynamic way. If you don't want to compress the data, you can simply remove the gzipStream wrapper. In addition, you can also change the order in which you want to execute the operations, simply wrapping in a different order. The decorator pattern provides you this flexibility.

The server side code is symmetric except that I decided to write the output to a file instead, using a FileStream.


Just for completeness this is the entry point of the program:


When you run the program the client send the message, the server receives and saves the message in a file that will be opened at the end.


The main Object Oriented Design principle respected by the decorator pattern is the Open/Close Principle.

Software entities should be open for extension, but closed for modification.

What? How can you extend the system without changing it?

You can create a completely new class that inherit from Stream and add it into the chain in any position you want. 

The streams hierarchy provided by .NET is open for extension but you don't need to change the code of the framework to do this (it is closed for modification). 

Source Code:
Decorator Pattern - Streams in .NET



Tuesday, 11 September 2012

It's all about Deliberate Practice - Talent Is Overrated



This has been an interesting reading.

What are the two principal explanations people give for top performance?

  1. Hard Work
  2. Gift from God
Research does not confirm this.
The most recent studies confirm that people with lots of experience were no better at their jobs than those with very little experience.
Some findings do not prove that talent doesn't exist but they suggest an intriguing possibility: that if it does, it may be irrelevant.
In fact how can you explain the following?
The extreme increases in top levels of performance in a wide range of fields over the past century have happened far too fast to be connected to genetic changes, which require thousands of years.
Wow!!! Can I become a top performer?

The answer is Yes.
Great performance is in our hands far more than most of us ever suspected.... but it's not that easy like you would like.
One of the example of top performance presented in the book is the story about Jerry Rice

What was his secret?
  • He spent very little time playing football: less than 1 percent of his football-related work to playing games.
  • He designed his practice to work on his specific needs.
  • While supported by others, he did much of the work on his own.
  • It wasn't fun.
  • He defied the conventional limits of age.
The secret is life-long period of deliberate effort to improve performance in a specific domain. The secret is what researcher calls Deliberate Practice.

Attention!

PRACTICE is different from DELIBERATE PRACTICE

What is Deliberate Practice?

It's designed specifically to improve performance.
Deliberate practice requires that one identify certain sharply defined elements of performance that need to be improved, and then work intently on them. The great performers isolate remarkably specific aspects of what they do and focus on just those things until they are improved.
Feedback on results is continuously available.
It's highly demanding mentally.
It isn't much fun.
Yes, you understood well. It isn't much fun!
It seems a bit depressing that the most important thing you can do to improve performance is no fun, take consolation in this fact: it must be so. If the activities that lead to greatness were easy and fun, then everyone would do them and they would not distinguish the best from the rest. It means that most people won't do it. So your willingness to do it will distinguish you all the more.
OK!

What can I do then?

Know what you want to do. 
The first challenge in designing a system of deliberate practice is identifying the immediate next steps. In deciding which skills and abilities to work on, and how to do it, you're on your own.
The best performers observe themselves closely. They are in effect able to step outside themselves, monitor what is happening in their own minds, and ask how it's going. Researches call this metacognition-knowledge about your own knowledge, thinking about your own thinking. Top performers do this much more systematically than others do; it's an established part of their routine. Metacognition plays a valuable part in helping top performers adapt to changing conditions.
Deep domain knowledge is fundamental to top-level performance. You don't have to wait for that knowledge to come your way in the course of your work. You can pursue it.
And what about creativity?
If we're looking for evidence that too much knowledge of the domain or familiarity with its problems might be a hindrance in creative achievement, we have not found it in the research. Instead, all evidence seems to point in the opposite direction. The most eminent creators are consistently those who have immersed themselves utterly in their chosen field, have devoted their lives to it, amassed tremendous knowledge of it, and continually pushed themselves to the front of it.
Creative people are focused on the task (how can I solve this problem?) and not on themselves (What will solving this problem do for me?)
And what about passion?

Yes, passion counts a lot.
In some fields, such as science and math, fascination with the available problems seems to drive excellent performers.
What about prodigious kids?

There are various theory but lots of research still need to be done.
Some kids are somehow born with a compulsion to work in a particular domain. In keeping with the principles of great performance, they become very accomplished because they're practising for huge numbers of hours. This explanation does not depend on any miracles, nor does it violate the ten-year rule; while these kids perform far in advance of other kids their age, they're still nowhere near world-class levels of achievement. That would have to wait much longer. In this theory, exactly why they were born with their specific compulsion remains a mystery. So far in the decoding of the human genome, no one has found a gene.
Different theory: some kids are born not with a compulsion to practise but with an ability to learn far more quickly than average in a particular domain. They practise all the time, setting new goals for themselves and increasing their skill, because their ability to learn makes it so rewarding for them.
As they began to receive recognition for the talent in the early years of instruction, the children's investment in the talent become greater. No longer was the prime motivation to please parents and teachers. It now became the individual's special field of interest.
Here you can find an interview to the author Geoff Colvin


Conclusions
What you want-really, deeply want-is fundamental because deliberate practice is a heavy investment. Becoming a great performer demands the largest investment you will ever make- many years of your life devoted utterly to your goal- and only someone who wants to reach that goal with extraordinary power can make it. We often see the price people pay in their rise to the top of any field; even if their marriages or other relationships survive, their interests outside their fields typically cannot.
Do you believe that if you do the work, properly designed, with intense focus for hours a day and years on end, your performance will grow dramatically better and eventually reach the highest levels? If you believe that, then there's at least a change you will do the work and achieve great performance.









Monday, 10 September 2012

Observer Pattern in .NET

Observer Pattern? Sounds complicated? Reality is that if you are a .NET developer you already know it and it is very simple.

The observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

But but but I can do this with events!

Oh yes :)

Events (and delegates) are the idiomatic way to implement the Observer Pattern in .NET.

Nothing new then.

Let's see an example just as a reminder.

Let's say I want to implement a class that generate numbers every so often (this can be a class that read data from a sensor for example) and notify clients when new numbers are generated.

This a possible implementation:



Considering the new features of C# 3.5 and LINQ that made the language more functional, an another way to implement this pattern is using delegates directly. 



The are more ways to implement this pattern but you got the idea. The framework brilliantly solve this problem and these techniques are actually used heavily in many contexts.

The main advantage of using this pattern is that the resulting system is loosely coupled. In this example, the number generator know nothing about the observers.

This is an important Object Oriented Design principle: Low Coupling


Strategy Pattern - Basic Calculator

Let's say we want to implement a simple calculator that is able to calculate a single expression using unary and binary operators.

The calculator should be able to interpret the following expressions:
operator operand
operand operator operand

Examples:
3 + 5
9 - 8
sin 0
cos 0

This is the first solution that come to mind:

This is an example of a client:

and a run:


What is wrong with this code?

I would say nothing considering the simplicity of the example. 

However, if you think a little bit you realize that this solution is not quite flexible as a client perspective. The client can use this Calculator class with a set of built in operations and he has no way to change this both at compile time and at run time. In order to support a new operation the library owner can simply add a new case statement, the client will be able to use the new operation but not to add new one at runtime. The Calculator will always have a fixed set of operations like implemented by his creator.

The strategy pattern allows you to build a more flexible system at runtime.

The strategy pattern defines a family of algorithms encapsulates each one and makes them interchangeable. The client does not need to change.

In our example is easy to recognize that the algorithms are the different operations.   In reality we can recognize two different families of algorithms: unary operations and binary operations.



The new Calculator will have two list of operations that will be used in order to accomplish the task. The Calculator class does need to know nothing about the details of the algorithms.

The client of our library now have the ability to use the Calculator provided by the library implementer but in addition is now able to generate a literally infinite number of calculators even with custom and completely new operations.

This is an example of how to create a calculator with the additional power operation with a syntax like in Python.






Saturday, 8 September 2012

Visual Studio Tip - Add Existing Item As Link

When you add an existing item in a project, Visual Studio automatically create a new copy of the file. This is usually what you want but sometimes you simply want to add a file as a link in order to reuse it and avoid to manage and maintain two different copies.

The trick is to use an "hidden" drop down menu in the "Add Existing Item" dialog.



You can see the effect because file added as link contains a special symbol (arrow) in the bottom left.


If you define macro in one of the project this technique allow you to share a file and customise it a little bit without the need to maintain two completely separate files. This is surely not a best practice but could be useful in some situations.

Visual Studio is clever enough to show you the code in grey based on where you open the file.




Friday, 7 September 2012

Book - 97 Things Every Software Architects Should Know

In this post I am going to share my opinions about the book I just finished to read. Till now, I simply limited myself in reporting the most interesting sentences from a book but starting from now (thanks to the constructive feedback of a friend) I decided to give more personal opinions and explaining what I really think. This is surely more difficult to do and more time consuming, but will allow me to deeply think and reflect about the books and set the stage for interesting discussions.


I am currently a software developer at the beginning of his career and I am willing to learn everything about software development and how to write better software. The role of the software architect fascinates me in some way and for some reasons is still a little bit unclear what are actually the responsibilities of one of them. Assuming this role could be a possible decision in my career so it is good to learn more about it. In addition, for personal projects like mobile applications you typically need to take architectural decisions and take care of all of the stages of the software development and the advices in the book can be useful.

Let's start to report the most interesting sentences in the book followed by my opinions.
A great software architect needs to master both sides of the architect's coin: business and technology
The fact that the software architect need to understand the business is very important and this is probably the most important reason why this is a separate role in the IT industry.
While it is important, even critical, to stay abreast of the latest trends and technologies, this should never happen at the cost of the customer. Always put the customer's long-term needs ahead of your own short-term needs and you won't go wrong.
This is a well know thing but it is always worth to remember. The need of our customers are the most important things and technology is only a way to solve a business problem.
Learning to treat people with respect, and learning give them the benefit of the doubt, is one of the core skills that turn a smart architect into an effective one.
Being able to work with people and respect them is a key element of any human being. It is always important to listen other people and be able to receive constructive feedback. This is for me a life principle and I truly believe in it. 
All too often, software architects sit in their ivory towers, dictating specifications, technology decisions, and technology direction to the developers below.
This is surely something that I don't like. As a developer, I would like to participate in discussions and contribute with feedback if I can. I like to know the "big picture", understand it. I like if architects take time (often) in discussing with developers the "big picture" because this, at least for me, help me to be more motivated and be more effective in my job.
Be sure to have a digital camera with you at all times (in order to take a picture of a whiteboard after a meeting).
This is surely something to remember and I have seen people in my company to do this. These days we always have our mobile phone in our pocket so this shouldn't be a big problem. In the future, we could have one of this 82'' LCD Multi-Touch Display in every meeting room :)
One thing most software architects fail to realize is that a software architect is also a leader. As a leader, you must gain the respect of your co-workers to work in a healthy and effective environment. Keeping developers in the dark about the big picture or why decisions were made is a clear recipe for disaster.
Same as a previous point. Everyone should know the "big picture" and surely the architect has the responsibility to simply share it.
By asking for the intended value of a requested feature or requirement, architects are able to address the real problem, and hopefully provide a better and cheaper solution than that suggested by the client. Arrange workshops and meetings where the architects focus is on customer needs - helping the customers to answer the "why" question.
One of the most important thing I learnt last year is the importance to start with why in everything you do. As an architect, you must care about the why of your customers in order to build the right solutions.
Experienced architects understand that they need to "sell" their ideas and need to communicate effectively in order to do that. Standing up automatically communicates authority and self-confidence. You command the room.
Because the architect is the bridge between business and technology there are often lots of trade off involved and the ability to communicate is key. This is an area where I need to learn a lot especially considering that I need first to master the English language.
No design is perfect from the start; all designs need to be modified as they are implemented. If you are also a developer on the project, value the time you spend writing code, and don't believe anyone who tells you it's a distraction from you work as architect.
It is important to accept that you can't design everything upfront in a perfect way. Adopting an iterative process is mandatory. In addition, a software architect is still a developer and I believe he should never stop writing code.
Commit and run is a crime because it kills flow. It's one of the most common ways for a developer to try to save time for himself, and it ends up wasting other people's time and is downright disrespectful. Why? Usually because it takes too long to build the system properly or to run the tests. Invest time in making the system fast to work with.
This is true and I have to admit happened to me sometimes. With very big projects sometimes the build time is very long and you need to do as much as you can in order to speed up the system but it is not always possible. At least, you shouldn't commit at the end of the day with the risk of breaking the build and create problems for your team.
The architect, in conjunction with development management, must create and nurture the means for regular, ongoing information feedback loops. A way is doing frequent releases of working software to the business starting early in the project.
I agree. When possible, involving the customers early and continuously in the project can be very beneficial.
A good architect should lead by example. He should be able to fulfill any of the positions within his team, from wiring the network and configuring the build process to writing the unit tests and running benchmarks. It's difficult to imagine how team members can have confidence in their architect if the architect doesn't understand the technology.
I believe that this is something theoretically true but practically extremely difficult to achieve.
"Fast" is not a requirement. Neither is "responsive". Nor "extensible". The primary reason why not is that you have no objective way to tell if they're met.
This sentence want to remember the importance of having requirements that can be measured (example: "Respond under 5 seconds").

Specifications alone have no value. The ultimate goal of a software project is a production system. A software architect must always keep an eye on this goal, and remember that design is merely a means to an end
Interesting. It seems that when you become an architect you love so much your design that you tend to consider it like the end result.


It is perfectly respectable for an architect to ask for help from the team. The team should feel it is part of the solution, but the architect should chair the discussion and identify the right solution(s).
The architect does not have to make the decision, he or she merely orchestrates the decision making process.
When I went to DevWeek 2012 I had the opportunity to discuss with a speaker (that was an senior architect) and I remember very well how much he underlined the importance of his team. As usual, it is all about trust.
Negotiating skills and a knack for influencing people can be valuable resources.
It is always good to learn more about psychology and it usually fascinate me.
Every software architect should know and understand that you can't have it all. It is virtually impossible to design an architecture that has high performance, high availability, a high level of security, and a high degree of abstraction all at the same time. There are several tools available to architects to determine what the tradeoffs should be when designing an architecture. Two popular methods are:
  • Architecture Tradeoff Analysis Method (ATAM)
  • Cost Benefit Analysis Method (CBAM)
I didn't know about this popular methods. Good to know.
Most software developers are optimists. Natural pessimists on development teams are often unpopular, even if they are consistently right.
I have one of my co-worker that is very defensive during programming. At the beginning I didn't understand some of his reasons but in the long term, I understood many things and he actually taught me a lot. If you want to design and develop rock solid products, you have to be a little bit paranoid (this is the word he like using), consider edge cases and test the system as much as possible. Never overlook the details!
Architects pour themselves into each design. Criticism of your creation feels like criticism of you. Defensiveness is easy. Learning to stop it is hard. Pride in our accomplishments is easy.
This is again obvious psychology. I think that it is extremely important to be able to accept constructive feedbacks and be open to suggestions.
How can we see quality? Aggregates large amounts of data and multiple metrics, such as method count, class fan out, cyclomatic complexity. Once a suitable view is available, software quality becomes a little less subjective.
Software quality is such an interesting topic and many organizations have lots to learn I think. I don't have strong knowledge about metrics but it is something I should look at more closely.

The post is getting longer than expected so I now simply share the remaining interesting quotes that are quite self-explanatory.
Accepting the fact that programming - or more precisely software development - is a processes of discovery and learning not a process of engineering and construction, is fundamental to bringing software practices forward.
As a developer you rarely get the time to sit back and really look at how the whole system fits together. AS an architect, this is your main focus. If you are doing a great job of being an architect, you really shouldn't have enough time to interfere with developers. You do need to watch closely enough to see that the design is being implemented as intended. It is reasonable to make suggestions when you see people struggling, but it's even better if you create the environment where they come and ask you for suggestions.
We say it to ourselves: keep it simple, stupid. We say it, but we don't do it. When an architect enters a project, there is an understandable desire to prove his or her worth. Showmanship, the act of appealing to your audience, is important in marketing, but it's counter-productive to leading a software development project.An architect must act in the best interests of his customer and not pander to the needs of his own ego. The simple problem-complex solution trap can be an easy on to fall into because we like to demonstrate our knowledge.
Never forget that you are playing with other people's money.
Software architecture is a craft, and it certainly takes practice and discipline to achieve success in the field.
Every time I make a decision about how a program behaves, I am really deciding what my users can and cannot do. It's not ethical to worsen the lives of others, even a small bit, just to make things easy for yourself. It's OK to release an application that only does a few things, as long as users value those things enough to pay for them. In fact, the earlier you release your application, the greater the net present value of the whole thing will be.
To be an effective software architect you must understand the basic architecture and design patterns, recognize when those patterns are being used, know when to apply the patterns, and be able to communicate to other architects and developers using them. It is also important to be aware and understand the various anti-patterns as well. Don't let your desire to exhibit design pattern knowledge could your pragmatic vision.
Sometimes the most important decisions are not about what you put in, but rather what you omit.
The architect should concede to good ideas and cultivate an atmosphere for ideas to grow. It is an open mind that will succeed in architecture. To the extent your responsibilities allow, you should do everything possible to empower your developers. Protect developers from non-essential parts of their job. Too much paperwork and too many office chores add overhead and reduce their effectiveness.
It should be made clear to you, your managers, developers, and other software stakeholders why one solution was chosen over another and what tradeoffs this entailed. Benefits:
  • It forces you to be explicit about your reasoning in order to verify that your foundations are solid. 
  • It can be used as a starting point to re-evaluate a decision when the conditions that influenced it have changed.
Assumptions should be visible and explicit for the sake of posterity and for future re-evaluation. It is even more critical to make sure that any assumptions that aren't based on relevant empirical evidence be validated before a decision is finalized.
The best and easiest way of working through it is to attempt to explain it to another person. We really want to share our knowledge and experience to help the industry progress; we also realize it helps us to understand and correct it.
Since over 80% of an application's life cycle is spent in maintenance, you should pay a lot of attention to the problems of support and maintenance when you're designing. Make the support lead a core part of the team. Involve a support lead with the planning for the application support. Design such that the learning curve for the support personnel is minimal. Traceability, auditing, and loggin are crucial.
Remember this: when you try to guess at future requirements, 50% of the time you're wrong and 49% of the time you're very very wrong. Get the application out the door on time and wait for feedback to generate real requirements.
Don't give in to the temptation to make your design, or your implementation, perfect! Aim for "good enough" and stop when you've achieved it.
The business is our reason for existence. Show the business domain experts the respect you expect to receive.
Don't use a pattern in your design that you haven't personally implemented before. Don't rely on a framework that you haven't coded against before. Don't use a server that you haven't configured before. If your architecture depends on design elements that you haven't personally used, there are a number of negative side effects: you won't be able to give good estimate, you will not know the pitfalls to avoid when using the elements and you will lose the confidence of your developers. When they ask questions about the design and you aren't able to give solid answers, they will quickly lose confidence in you and your design. Before anything, an architect is a developer.
Ingenuity is a key trait of successful architects. However, an equally important characteristic of the activities of a successful architect is diligence. It is an exercise in perseverance and paying the right amount of attention to each task and each architectural goal of the system.
You should not claim that an architectural decision has been made until the following two conditions are met:
  • A decision has been put in writing because architectural decisions are rarely trivial. They must be substantiated and traceable.
  • A decision has been communicated to the people who execute it and the people who will be affected directly or indirectly.
Clever software is expensive, hard to maintain, and brittle. Don't be clever. Be as dumb as you possibly can and still create the appropriate design.
You need to carefully select your development team and diligently protect it once assembled. Good developers are often strongly motivated by recognition. Use this fact to your advantage and acknowledge stellar performances. Finding great developers is difficult; letting people know they are valued is not. Don't miss simple chances to build morale and boost productivity.
I would like to finish with a quote from Grady Booch:
Grady Booch: "All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change".
An effective architecture is one that generally reduces the significance of design decisions.


Saturday, 1 September 2012

Goodbye to my technical paper books!

Since I moved in UK I never had the time to throw all my books from the big display cabinet in my living room in Italy. This mean that I forced my parents and my sister not to use the display cabinet for such a long time.

Today, I decided to select all the books that I can remove from there and put in the bin.

It is a little bit sad but this is the time when some cleaning is required. Any of these books in some way shaped me and my professional knowledge but all of these are obsolete and surely I don't plan to read them again or use them as a reference.


Hopefully, I will not have this problem any more in the future because I am now only buying eBooks. The Kindle is absolutely my favourite device and it changed my life radically. Now, I can brings thousands of books everywhere and access them any time.

There are some books, however, that have a special meaning for me and even if they are obsolete I could never throw them. In particular "Da Visual Basic a C#" is the book that introduced me to the C# language and the .NET Framework that is actually my favourite platform and where I invested professionally my last years. "Algoritmi in C" has been the book that I used to prepare myself to the  Italian Olympiad of Informatics in 2003 and to prepare my secondary school thesis about algorithms analysis. The other two books are the books that introduced me to VB when I was 13 years old.


Here other books that I want to keep for reference and that I will consider to bring in UK or simply buy a new digital version of them.



If you are still not sure to buying an eBook reader you should consider how the "weight" problem is brilliantly solved by these devices. In the future, I will always have access to my full books library and I will never have this problem.

Here you can access the list of all the books I read:
http://www.anobii.com/angellaa/books