Friday, February 29, 2008

Visitor plus one

In this weeks assignment I added the visitor pattern and the singleton pattern to my project.

I have one Antivirus visitor that has two states (scanning and disinfecting) and visits computers and a Name visitor that visits with viruses and assigns them random names generated from several arrays and Random.nextInt().

To implement the visitor pattern, you first need to decide what objects will be the visitees and provide setters and getters for any state changes that need to be performed by the visitor. Then you have to add an acceptVisitor(Visitor v) method to each visitee class that tells the visitor v to visit it. You should create a visitor interface that has methods for visiting each class of visitee and implement this in each of your visitors. In each visitor, you must implement the methods in the visitor interface and then can perform actions on the visitee. 

Antivirus seemed like a natural place for the visitor pattern because it allowed me to simplify my project considerably. Previously I had an instance of antivirus that was 'owned' by each computer, but the visitor allowed me to pull out all that code and replace it with the acceptVisitor methods.

I used the singleton pattern in my project to ensure that only one instance my Antvirus visitor and Network class would be created because there was no need for multiple instances of them. The singleton is a very short pattern that creates an instance of the class if none exists and then returns that instance, or if it already exists, just returns it.

Wednesday, February 20, 2008

Four Patterns in Concert

For assignment 6, I decided to model a class of 4 students and a lecturing professor. The students observe the professor, who has 2 states: OnTopicState and OnTangentState.

When the professor is on topic, the students use the strategy pattern to set their listen() behavior to AttentiveStrategy and uses a System.out.println to print what the student is doing (taking notes, listening, or distracted).

When the professor is on a tangent, the students have their listen() behavior set to SpaceOutStrategy which can make the student print out that they are sleeping, doodling, browsing the internet, daydreaming, or paying attention and amused.

The students are decorated with Freshman, Sophomore, Junior, and Senior, which have info() methods that return a String with the students name and class.

A standard class period in my program is 50 minutes long and the professor will pick a random amount of time between 1 and 25 minutes to either be on topic or on a tangent before the state is switched. When the class timer reaches 0, the class is dismissed and the students leave.

I decided that my console output was pretty boring when I finished implementing the patterns, so I added String arrays so that the teacher would lecture on different topics and go on tangent about different things similar to how I made the students have several options for their listen() behaviors.

I had a lot of fun with this project and feel like I can now go back to my more complicated project with a better idea of how to compose patterns and not let all the details obscure the implementation. 

Friday, February 15, 2008

State Pattern Ideas

I haven't implemented my state pattern yet, but I'm planning on retooling the way that my Computer class stores whether or not it is infected. I'm going to add states for being infected, clean, or hosed by a virus. The other place I will add the state pattern will be my Virus classes. I would like my viruses to have states for Seeking computers to infect, infecting a computer, and hiding from antivirus.

State Pattern Recipe

You'll first need to determine the object(s) you'd like to apply the state pattern to and what states and transitions will be needed. Use a state diagram like the one in Head First Design Patterns if you want to visualize this properly.

1.) Create a State interface
2.) Write methods for the state transitions
3.) Create a class that implements State and add the state methods as specified in the interface
4.) in each state change method, you can use if/else statements to check the current state and offer different responses based on what state the object is currently in
5.) Create instance variables of type State for all your states and for the current state, which should be assigned to the state that the object should start in
6.) create a setter method that lets you set the state and a getter method so that you can get the current state

You now have a sort of rudimentary AI that can do different behaviors based on the current state.

Friday, February 8, 2008

Decorator Pattern Recipe

1.) Figure out which decorations/wrappers you'll need
2.) Create an abstract Decorator class that extends the superclass of the objects you wish to decorate
3.) Create wrapper classes that extend the decorator class. The constructor should take a reference to the object the class is to wrap so that you can use the methods in all layers of the decorated classes
4.) Define any methods from the abstract class
5.) To wrap an object up in a decorator, all you have to do it assign it to your decorator and pass it into the constructor.

Thursday, February 7, 2008

Decorator Pattern Afterthoughts

The only issue I ran into with my plan is that if I used the decorator to control whether or not the Viruses can disable antivirus, then I'd be  essentially replecating what I've done with the strategy pattern. For now, I'm just using decorator to make viruses 'stealth', and give them the ability to kill computers. When I think of another use for the strategy pattern, I'll implement it there and then add to my decorator pattern.

Decorator Design Ideas

I'm planning on implementing the Decorator Pattern to give my TrojanVirus and WormVirus classes different capabilities. Basically, I would like to be able to arbitrarily give some viruses (but not all) the ability to do things like be invisible to antivirus, disable antivirus, tunnel through firewalls, take down firewalls, and hose computers (effectively removing them from the simulation).

Observer Pattern: Check!

I finally implemented the observer pattern successfully! It was quite a triumphant moment seeing my classes do stuff without me explicitly telling them to. The observer pattern reminds me of a magic trick. It's clear what's happening behind the curtain, but if I didn't know about the pattern, I might think that somehow my java classes picked themselves up and became slightly sentient.

What I ended up doing was having my Computer class be the observable and then having the instance of antivirus that is created by each computer observe for virus infection. Whenever a Computers boolean isInfected variable is set to true, changed() is called which updates the antivirus instance. When antivirus gets wind of an infection, it checks to make sure that it's enabled and then calls setInfected(false) which sets the isInfected boolean in the computer class to false. This would cause antivirus to get updated again, but since the computer isn't infected, it doesn't do anything.

The second place I implemented the pattern was to have each instance of Computer be an observer and antivirus the observable. This lets the computer's know when their antivirus has been turned on or off. I'm not sure I'll end up using this implementation farther down the line, but it seemed like as good of a place as any to stick the second observer implementation for now as I'm still running with a fairly small amount of classes.

I'd like to mention that I found the extra lecture and lab time devoted to the observer pattern extremely beneficial for my understanding of the pattern. I also met with Daniel earlier in the week to run my ideas past him, which was very positive as well.

Monday, February 4, 2008

Observer Recipe

First you need to figure out which object(s) needs to be the subject and which ones need to be observers.

Then you must decide on whether to use Java's built in observer implementation or if you'd rather create your own infterfaces for Subject and Observer.

If you create your own, you must have methods in the Subject interface for adding and removing observers and for notifying observers that the subject's data has changed. Then in the Observer interface you must have a method for updating the observers with data from the subject.

You now need to implement the Subject and Observer interfaces in the appropriate classes so that you'll have one subject and many observers. The constructor of each observer class should register it with the subject class by calling registerObserver(this).

Now, you can either push out data, sending out whatever the subject has and letting the observers use what they want, or pull specific pieces data into the observers from the subject directly. The pull method requires more getter methods in the class that implements Subject, but seems like the better option in terms of keeping the observers on a need-to-know basis.

In the Subject class, you must create an arraylist to store the observers in and implement the subject interface. If you're going to push data, then you should create a dataChanged() method that will call notifyObservers() whenever the data is changed. notifyObservers() will iterate through the arraylist, pushing each observer the updated data. If you're going to pull data from the subject, let notifyObservers() cause the observer to use the getter methods of the subject class to pull the updated data.

Now, to test your implementation of the Observer Pattern, you need to create an instance of the subject class and observer classes. When you create the observer classes, pass the reference of the subject class to their constructor so that they will be added to the observers arraylist by their constructors.

When you change the data in the subject class, the dataChanged() method will be called, which will in turn call notifyObservers(). From here the new information will either be pushed or pulled to the observers.

If you use Java's built in observer, you don't need to worry about creating the two interfaces. You will need to have the subject class import and extend observable and the observer classes import and implement observer. You'll then need to use setChanged() and notifyObservers() to update the observers. Register observers with addObserver().

Rejoining the land of the living

I took a beating from the flu (or some other nasty bug) during the later half of last week. I've regained most of my ability to use the higher functions of my brain, so I'm now trying to dig myself out from the hole that I'm in.

I've re-read the most juicy bits of the Observer chapter and come up with my recipe for the pattern which will be posted in the next entry. I started using the Java implementation of Observer in the version of my project that I have emailed in, but want to implement my own Observer and Subject interfaces instead. I will continue to hammer away at getting the Observer pattern implemented naturally in two places.

The most obvious place I can think of putting it is to allow antivirus to monitor the computers on the simulated network. The antivirus will be updated whenever a virus tries to infect a computer and if it is enabled, will disinfect the computer before the virus has a chance to mess anything up. Where I'm running into trouble now is where to have the second implementation of the pattern. Once idea that seems decent is to let viruses of the WormVirus class observe the firewalls of computers that they are port-scanning, and be notified of ports when they become open.

Do these two spots sound like good uses of the Observer pattern?