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.
No comments:
Post a Comment
What you think about this post? I really appreciate your constructive feedback (positive and negative) and I am looking forward to start a discussion with you on this topic.