Apr 26, 2010
In a software that I'm developing, I've a problem, I'm searching a solution for that, and I think that a solution can come from a design pattern, so I'm here for some suggestions.
The software must connect to a server, the server can be of a different type (for example FTP and SQL), after the connection the software must perform some actions, for example download a list of something.
We have different type of server, so if the software is connected on a FTP server, the action is download a list of files, if the software is connected on a SQL server the action is a query on a table.
When the software starts, it loads a configuration file, on this file there are some server informations, what happen in reality is a population of a list of ServerInfo objects, each object contains the server type, the address and the login data.
I'm searching an elegant and transparent solution, I don't want code like this:
Studying the problem I've found a possible solution with the Abstract Factory pattern, but I'm really new to the world of desing patterns, so I'm not sure if this is the correct solution, and I don't understand very well how to model my problem on this pattern.
if (serverInfo.type == FTP)
server = new FTPServer();
else if (serverInfo.type == SQL)
server = new SQLServer();
May 11, 2010
The right design pattern to apply depends really on the following:
Since I don't have much information about your project, I'll throw a few scenarios.
- Do you really have a family of components that need to play with each other?
- How much commonality do you have between the variation points, e.g., FTP and SQL servers?
- Is a design pattern really need it? Is it a one-time throw-away code or a long term product that needs to be designed with extensibility in mind?
I hope that helps.
- If your design is a single-entry point, i.e., one-class component which then knows how to instaniate other classes, then the most seamless way is to store the full class name in a config file, then at run time, read that class name string from the config file and dynamically instantiate it. No 'ifs' or 'conditionals' there.
- On the other hand, if you have many components that need to interact with each other at run time, you can implement an Abstract Factory to create the consistent family of components per server type or variation point. For example, if it is 'FTP' in the config, then the factory would create an FTPApp, FTPGui and FTPGateway etc... if it's 'SQL' then the factory would instantiate a SQLApp, SQLGui, SQLGateway etc... all consistent family. In this case, your interface would be coarse-grained and would only include high level methods such as Initialize(), Connect() and Close() and each concrete class would implement the details. They'll play nicely together because they're all from the same family.
- If both the above options are not to your liking then implement a Simple Factory where it simply reads which server class to instaniate from the config file and instantiates that. Not much in common there.
Apr 29, 2010
Sorry i just read the complete post, so I have to update.
I don't see much room for a generic base behavior in your case. Let's take an example of getting Data.
server.GetData(string uriOrFilePathOrQueryStringEtcEtc) but what will it return. Let's say you choose XML, so it will be able to cover hierarchical nature of your ftp directory structure, as well as the result of a query from Sql Server. Ok case handled.
What about renaming a file. Renaming a file is totally different from updating a record. parameters are totally different from each other. Ftp will include other operations like server.MakeDirectory, server.UploadFile
To make all these servers adhere to a standard interface, we may end up writing a very very tricky code, I think what you were thinking of was something like this
and then make up you concrete servers on this basis. and then implementing your concrete servers like
The problem I see is too much different parameters, and disagreement on a base interface, which rules out the application of factory method. Now as far as Strategy is concerned, I see the same problem.
Apr 27, 2010
Sorry but I'm very new in this world (Design Patterns), and now I'm very confused :-(!
I don't understand if the solution is Strategy Pattern or Abstract Factory Pattern.
Apr 27, 2010
Yes, I do agree, with the requirements that when any one connects to server we must be able to perform operations like
What we need to do is that, by looking at the requirements, in Abstract Factory we will have an abstract class which is like a template class where all concrete classes will implement the same. Here we don’t have any as such common functionality. That is where I was looking at.
But what we can also do here is that, for each Server we can have one Abstract Factory written. But it will be huge efforts for us J
- On FTP: Add file, Delete file, Edit file, Add folder etc...
- On SQL Server: CRUD operations (Create, Read, Update, Delete)
Apr 27, 2010
I don't understand if that's the correct/right pattern for my problem, but sure, I'm here for learn.
After the application starts, and after the server selection has taken place, the app is always connected to the server. The user can perform different operations, for example, add data (a file or directory if we are connected to an FTP server) or add a value to a table (if we are connected to a SQL server).
Plus, I need a global access to the server class, like a Singleton, because it will be accessed by serveral classes throughout my application.
You presented a nice solution and the Strategy Pattern looks very interesting.
So, am I right to think that I will need a Singleton 'wrapper' class?
Apr 27, 2010
Abstract Factory Pattern is concerned about creating families of related/dependent object. As the requirement is, based on the configuration application will connect to different server. After that you will be retrieving data from the server.
So you are not really looking for the object that are getting created or you are not concerned about the object returned. Only the need to get the collection that is having strings.
There are two algorithms, connect to FTP/SQL Server and get the data. These are two different behaviors and Data. So what we need to do is implement these algorithms in to two different classes and provide an encapsulation in one classes and make them interchangeable based on the configuration. So we will need to implement Strategy pattern here. Even if in feature we can also hook-up with the new server.
I don’t see any scope for the Abstract Factory Pattern here, until unless we are developing complete custom framework for data access layer. If you had developed one, it will on the Abstract Factory.
Any suggestions, always welcome