Coders Corner
By: Gamma Cpt Zerhash
This is the second column that I have posted. Last issue we spoke about ’sed and awk’, 2 very useful tools for the linux cli (command line interface). Last issue was completely practical and this week I will take you into the realm of contextual.
The GoF (Gang of Four: Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides) released their book in 1994 and has become a standard for object oriented development. I will start off by saying that nothing in this world lasts 15 years in IT, however these guys have hit it. Their concepts aim to “create reusable designs without having to rediscover the design solutions themselves”.
So unlike the travesty of legacy code, we can update code in a objectified manner without repetition. Attack the problem of updating head on, without having to focus so much on how the solution is acquired.
These concepts have been applied to Agile development which is a collection of best practices. Practically and conceptually I will be involving more and more of these practices. I may even step into more specific areas such as Extreme and Scrum development, or just project management as a whole.
I will be using UML(Unified Markup Language) to describe concepts and to be honest this knowledge is important to software design. On top of agile, extreme, and scrum development. However I am not about to baby anyone into this, nor am I interested in being so esoterical that nobody gets what the intent is.
So I have introduced this beast known as the GoF and Agile development, now we are going to apply something. This is what it is all about. I will use java for this however, rest assured you can do the exact same thing in any other language provided it can handle object orientation.
The Strategy Factory
For this month we are going to be using SNEAK as our code. I figure, we may as well talk about our open source project that has reached its full release to the desktop. The “Snarkles.Net Encryption Assortment Kit” has a load of different ways to mash up your text. The desktop version has two separate invocations; one by GUI (Graphical User Interface) and the other by CLI(Command Line Interface). This brings us to our first problem domain. How do we make this system use the same algorithms irregardless of the interface. The term is “Loose Coupling”, which means that all interfaces will be able to work without having to worry about other interfaces.
For an example, if I had the “DES” cipher hooked in to work when a person hits the drop down list and selects “DES”, I could code this right into the GUI. Giving a very short gap to jump between the programs logic and the user interface. As time goes on we keep adding and adding to the interface. Eventually, big boss man Church comes online and says, “Let there be CLI”. We are then left with playing catch up with all of our functions and dumping them into the CLI.
A week later Church notices logic error in the code, the CLI isn’t doing things the same way as the GUI. In fact people have been forgetting to port their code over to the CLI after coding it for the GUI.
Here comes the Strategy Factory!
In the design world, a factory refers to something that is responsible for creating adaptors. An adaptor is simply a way to couple one thing to another. Our adaptors are all the different ways we encrypt and decrypt. The Strategy Factory is simply responsible for returning the right one. If there is no way of doing what the interface asks for it should give an error back to the interface.
So rather than having the interface deal directly with the algorithms it deals with the factor which will deal with the ciphers.
So now we look at the code:
package net.cyberarmy.sneak;
import net.cyberarmy.sneak.algorithm.*;
import net.cyberarmy.sneak.algorithm.template.AlgorithmAdapter;
import net.cyberarmy.sneak.algorithm.template.AlgorithmException;
public class StrategyFactory {
static StrategyFactory SELF;
/*
* This is a design pattern meant to divy up the strategies in a logical
* way.
*
* This is used to separate the algorithms from the user interface.
*/
private String[][] ITEMS = {
//Name, Documentation, CLI Arguments to respond to
{"ASCII to Binary", "Convert an ASCII String to Binary", "-ab" },
{ "Binary to ASCII", "No Doc", "-ba" },
{ "ASCII to Hex", "No Doc", "-ah" },
{ "Hex to ASCII", "No Doc", "-ha" },
{ "URL Encode", "No Doc", "-ue" },
{ "URL Decode", "No Doc", "-ud" }
};
public static StrategyFactory getInstance() {
if (SELF == null) {
SELF = new StrategyFactory();
return SELF;
} else {
return SELF;
}
}
public AlgorithmAdapter getAlgorithmStrategy(String s)
throws AlgorithmException {
if (s.equals(ITEMS[0][0])) { //"ASCII to Binary"
return new BaseConversionCode(10, 2, true);
} else if (s.equals("Binary to ASCII")) {
return new BaseConversionCode(2, 10, true);
} else if (s.equals("ASCII to Hex")) {
return new BaseConversionCode(10, 16, true);
} else if (s.equals("Hex to ASCII")) {
return new BaseConversionCode(16, 10, true);
} else if (s.equals("Binary to Hex")) {
return new BaseConversionCode(2, 16);
} else if (s.equals("Hex to Binary")) {
return new BaseConversionCode(16, 2);
} else if (s.equals("Backwards")) {
return new ReverseStringCipher();
}
Etc.....
else if (s.equals("URL Encode")) {
return new URLEncode();
} else if (s.equals("URL Decode")) {
return new URLDecode();
} else {
return null;
}
}
public AlgorithmAdapter getAlgorithmStrategy(int item)
//return the algorithm by the strategy item number
}
public AlgorithmAdapter getAlgorithmStrategyARG(String arg)
//code that returns the algorithm based on which CLI Argument was passed
return null;
}
public String[] getSupportedList() {
//Return the list of what is supported
}
}
Ok so I just dumped a lot of code on you. I deleted a lot of th actual simantics just because they aren’t as needed.
Get Instance
This is a convention that results in what is called a “Singleton” pattern. If we instantiate the class with ‘new’ a lot of times, then the result will be a lot of instances of the class for the purpose of only returning one object. This is inefficient. As a result we store the instance of the class within itself, and as there are requests for the object, we return itself, otherwise we create it. If I want to further develop the code I would set an array of all of the objects so that they are treated as singleton. There isn’t any reason to have any more than one instance of each cipher, however I would have to examine all of the code prior.
Get Algorithm Strategy
This is where we take any form of identifier and we link it to a cipher and return it. After this the factory doesn’t really have anything more to do. This is the core of the class. If there is nothing I return a null. That way the other programs don’t require to know anything about the capabilities of the class. So this results in loose coupling. We can further loosen the coupling by using class loading. That would mean that the system can be extended by just putting a new class into the directory. However I think that this gets the point across.
Other Fixins
The Items array holds the names of each of the items and in order of item. So when we return it the GUI will know how to request the ciphers. The get strategy by ARG, is an interface for the CLI, the arguments are in the Items array. This is something that can be pushed out to the adapters. The StrategyFactory is a bit over burdened with worrying about who’s who in the zoo when adapters can handle that.
Conclusion
It is hard to get the true essence of a design pattern without stepping into other patterns. As SNEAK is released this month to its first revision for the desktop. It is only fitting to touch upon how some of the task was done.
“Design Patterns: Elements of Reusable Object-Oriented Software”, ISBN 0-201-63361-2,http://www.informit.com/store/product.aspx?isbn=0201633612
http://www.agilemodeling.com/, Scott W Ambler
http://www.apwebco.com/gofpatterns/creational/FactoryMethod.html
This is the best zine EVER!! lol
sered secrets inside!!
excellent work.
Great article!
I’m currently working on a cryptography algorithm aswell if anyone wants to have a look;
http://www.codeplex.com/Rexor