Wednesday, January 30, 2008
Design Patterns Quick-Reference
Friday, January 25, 2008
Strategy Pattern (Lab 2) Redux
Going from a standard OO design using inheritance and abstract classes to one using the Strategy Pattern isn't all that huge of a leap. Instead of having to override behaviors in subclasses that are unable to perform them, you can use a variable to store the type of behavior to perform and then use an interface to perform the behavior.
Joe's problem with SimUDuck stemmed from the fact that he needed to extend it in a way that would add too much complexity to be easily maintained. He was trying to use inheritance to add a fly() method to every sub-Duck by adding it to the main Duck class. This had the unintended effect of granting flight capability to all sub-Ducks, including the ones that aren't supposed to fly: RubberDuck and DecoyDuck. If SimUDuck was a project that would never need maintaining or extending, it wouldn't be too bad to just override fly() in the few subclasses that aren't supposed to fly, but since this project is one that was still in progress, using inheritance and overrides would lead to major headaches for Joe. While this is a valid use of shadowing, it's confusing and doesn't lead to reuse of code.
The Strategy Pattern is a good solution for the problem Joe was faced with because it separates the behaviors from the objects that perform them. The big payoff is that after implementation, the Strategy Pattern provides a more organized and understandable way of reusing and unifying a method across a hierarchy of animates. Joe can add sub-Ducks whenever he wants and make changes to existing behaviors with very little effort compared to if he had just stuck with his standard OO design.
Part 2:
To implement the Strategy Pattern, follow these steps:
1.) Figure out which methods/behaviors are used multiple times across the hierarchy. ex: fly(), quack()
2.) Come up with a naming convention so you can keep all your behaviors straight and create classes for each of the distinct variations of the method, bringing the methods out of the superclass. ex: remove fly() from Duck and create fly(), nofly(), etc in the new classes
3.) Wrap the different versions of the behavior with an interface that can be called when behaviors need to be performed. ex: performFly()
4.) Reference an object of type interface (or rather, whatever you chose to name your interface) and use this object to set up which behavior to use
5.) Change the method in the base class to call the object from above and perform the appropriate method through the interface
Oliver is the 'Observer' cat on the copyright page and was surprisingly difficult to spot since it wasn't on a page that I read the first couple of times. Good trick to get us to re-read the section! :)
Sunday, January 20, 2008
Strategy Pattern (Lab 2)
1.)
Even though the Strategy Pattern adds complexity in terms of the number of classes in your project, the most striking benefit is that it provides a more organized way of modeling the interaction between the subclasses, interfaces, and abstract class by separating the code for executing the behaviors from the animate classes. Another benefit is that you have less duplicated code because the interface for each behavior handles all the work for each of the animates.
Joe's problem was that the relatively simple SimUDuck app needed to be extended in a way that would add a behavior to the subclasses of Duck. Joe's lack of design pattern knowledge led him to leverage inheritance to add a fly() method to Duck. The flaw with this is that every subclass that extends Duck will now be able to fly, even if it's a RubberDuck or DecoyDuck. It wouldn't be too bad to override fly() in the few subclasses that don't fly, but if Joe's manager decided that they wanted to add every variety of duck, living or otherwise, to the simulation, Joe would have to spend many a late night adding overrides to all of the sub-Ducks that can't fly. The Strategy Pattern is great for the SimUDuck project because it's easy to change and when you add methods to one of the behavior interfaces, you don't have to worry about messing up like Joe did and granting a behavior to an animate that shouldn't have it.
2)
-Sort out the methods of the superclass that vary from subclass to subclass. In the SimUDuck example, the stuff that changes is the various implementations of the fly and quack behaviors.
-Create interfaces for your behavior that hide the nitty gritty details of the implementation from the subclasses. The two interfaces in SimUDuck were FlyBehavior and QuackBehavior.
-Add classes for each variation of the stuff that changes that implement the interface, also add instance variables to each subclass that get passed to the interface and tell it which variation to perform. In SimUDuck, each Duck subclass makes calls to the behavior interface and passes it it's own behavior instance variable.
Now, when a Duck calls the performFly() method, the behavior is delegated to the FlyBehavior interface's fly() method which performs the behavior specified by the instance variable.
Thursday, January 10, 2008
Project Proposal
My idea for the term project takes cues from XKCD (a webcomic) and involves simulating the spread of computer viruses through a network of computers. The simulation would be turn based, in the sense that for every period of time, each animate object would be alloted one action.
Each simulated computer would be assigned a unique IP address and would be able to exchange email, execute email attachments, and visit a selection of simulated websites and download files from them. Individual computers would also need to have their own email addresses and address books, containing the addresses of a random selection of other computers' on the network.
Some machines would act as clients, with only one connection to the rest of the network, and others would be servers, which would have many connections. The computers would have antivirus and firewalls (though not all of them would have these security features enabled) and they would also either be up to date with the latest security patches and virus updates or not be up to date.
I envision three to four types of viruses existing in this simulation, but there is room for more if I can think of how to implement them. E-Mail Trojans would e-mail themselves around the network to single or multiple recipients who would be infected if they executed the attachments, Worms would scan network for open ports on computers that do not have the latest security updates. Some of the viruses would be able to defeat antivirus software and disable firewalls, and others would simply take down machines. Resident Viruses would embed themselves in files that would be downloaded from the 'internet' by the computers and would infect them upon being executed. Malicious code could also exist on websites, mimicking some of the nasty Active-X scripts that exist on the real internet.
For the simulated web-browsing to work, there would need to be a list of available websites, some of which would contain malicious code, and others would be clean. If a computer is browsing the web, it has a chance of downloading a file from the website, which may or may not be infected.
Antivirus software would be able to scan the computers for viruses and then attempt to remove any that they find. The viruses would all have a creation date, and each instance of the antivirus software would contain a variable storing the date of the most recent virus definition update. These two dates would be compared in order to decide whether or not the antivirus software would be able to remove the viruses.
The animate objects would obviously be the active viruses, since they would be move about. The resident viruses and malicious web code would be inactive because the computer would have to perform an action on them in order to be infected. The computers could also be considered active, since they will send emails and browse the web without necessarily being infected. Antivirus software would be able to scan for viruses and then remove them if any were found, this makes them reactive inanimates, since the antivirus software won't be moving around.
The hierarchies in this projects would consist of:
Animates:
- Computers
- Worms
- Email Trojans
Inanimates:
- Firewalls
- Antivirus
- Resident Viruses
- Malicious Web Code
Locations:
- Each simulated machine would be it's own location
Actions:
Computers - visit website, download file, send email, read email, execute email attachment
General Virus Actions - infect, disable antivirus, disable firewall, disable automatic updates
Worms - scan ports, exploit security hole
Email Trojans - get contents of email address book, propagate through email, format c:/
Antivirus - Update definitions, scan computer, remove/quarantine virus
Resident Viruses and Malicious web code - infect computer when file is opened or website is visited