Java

I gave up with Design Patterns in Java – I start my book

September 26, 2010 C#, Design Patterns, Java, Opinion, Personal, Success 12 comments

Yeah, title sounds not logically, but you will understand in a few why it is still relevant to this blog post.

It was and it is a good idea to…

In one of my blog posts I’ve decided to have all of the GoF Design Patterns written with Java. And idea itself is very good. Having all of the design patterns written by your own with you own examples gives you understanding of the DP that you cannot gain anywhere else plus to that if you have industrial experience of using all of them you can start think that you are guru of DP.

Process of writing my post on one of the Design Patterns looks like this: I read chapter of the GoF book on the particular DP, then I think up my own example if I do not have it already in my mind and after I’m done with some preliminary ideas I search over the internet for interesting articles on it and probably rethink some of the aspects of my example. After all of that I proceed to writing blog post and source code with Java.

Conclusion: Awesome and probably one of the best ways of learning DP is to have your own example of using it and industrial experience.

Design Patterns articles

One of the intents of having DP written in Java was to familiarize with that language. But it turns out that I did not learn much from Java (except of few things). Also few months ago I started keeping up Tuesday’s Design Pattern on the Lviv .NET User Group Page. Since it is .NET specific UG, I used to do following: 1) translate and 2) translate. In first place it is translation from English to Ukrainian and in second from Java to C#. When with item number one I have to apply some logic and rephrasing I cannot say the same about second item. I just copy code-paste code into Visual Studio and change few keywords. So what do I learn regarding of Java in this case?

I will continue learning Java, but I have to consider better way of doing it. I will also continue writing about Design Patterns, but with examples in C#.

Conclusion: Learning another programming language (Java) is really great idea, but be sure that you choose right approach of doing this.

First free e-book

On the road to Lviv I got perfect idea to start my first book. Of course this cannot be comprehensive stunning author’s book, but I have to start with something. In other words some probing book and this could be this “try it” case. I’m almost sure that there are no books about GoF Design Patterns in Ukrainian. (I suppose that there are in Russian, which can be easily understandable for most Ukrainians…)

How this book will be different?

  • It will be in Ukrainian.
  • It will NOT be a translation of GoF book in any way.
  • It will have my own unique examples.
  • It will be short and easy to understand.
  • It will be really cool kick-off book on DP for starting Developers.
  • It will be free to download.

Why do I need it?

I understand that this book might not be popular at all. But I have to start with something and plus to this it will help me familiarize with the whole process and build my confidence for future.

Also if you have some doubts about my idea I have a question for you: “Have you ever dreamt about your own book? If yes, do you have at least small book written?”

Conclusion: Never be skeptic about starting your first book. It might be a huge step to your success as anything else you are hesitating about but still dreaming about it!


12 comments


Prototype

July 24, 2010 Design Patterns, Java 1 comment

Have you worked with Outlook calendar or any other mature calendar, that allows you copy some events from day to day?
For example your friend scheduled small beer party for Friday, 23 July where he listed his friends, also he allocated time from 7pm till 3 am and put high priority, he also described that it is great to have party on Friday after work in the comments. As you were invited, party went extremely well. In the end of party your friend decided to schedule similar party for the next Friday, but since he had already drunk too much it was complicated for him to populate all of the fields of the event in calendar. Which kind of enhancement would you propose for the calendar, your friend uses? Probably copy-paste functionality.

PROTOTYPE

Prototype is design pattern, that allows us create complete copies of instances already defined in design (list of possible types of events) or either run-time(Friday’s event), so we no longer need reinstantiate them from A to Z. Already defined instances are called prototypical instances.

As we already described one applicability of Prototype for copying instances specified at run-time, this design pattern could be also used for reducing number of subclasses in the system. For example instead of having subclasses like “5 floors apartment block with 3 rooms flats“, “9 floors apartment block with 2-3-4 rooms flats” and “12 floors apartment block with 1-2-3 rooms flats” you may have 3 instances of ApartmentBlock initialized with needed properties, and then you just copy one of them when you need to build new building somewhere in the city. In other words no need to write either this “new ApBlockWith9FloorsAnd234Flats()” or this “new ApartmentBlock(){Floors = 9; FlatsDic = {2,3,4}}“.

What you need is something like “_9FloorsApBlock.Clone()“. Of course you can combine this with FactoryMethod, so you will have something like “GetMe9FloorsAppBlock()“, which inside calls cloning of prototypical instance.

Example

Let’s now take a look at Prototype, which defines clone() method for our prototypes.

public class CalendarPrototype implements Cloneable{
    @Override
    public CalendarPrototype clone() throws CloneNotSupportedException{
        CalendarPrototype copyOfPrototype = (CalendarPrototype)super.clone();
        return copyOfPrototype;
    }  
}

My concrete Prototype class is calendar event, which looks like this:

public class CalendarEvent extends CalendarPrototype {

    ArrayList<Attendee> _attendees = new ArrayList<Attendee>();
    Priority _priority; // priority is reference variable  
    Date _startDateAndTime = new Date();
   
    //setters and getters here
}


Client code
is executed, when my friend wants to open calendar, right click on event and paste it into other location, therefor changing start/end date & time.

Take a look on this process:

public class PrototypeDemo {

    public CalendarEvent getExistingEvent(){
        CalendarEvent beerParty = new CalendarEvent();
        ArrayList<Attendee> friends = new ArrayList<Attendee>();
        Attendee andriy = new Attendee();
        andriy.FirstName = “Andriy”;
        andriy.LastName = “Buday”;
        friends.add(andriy);
        beerParty.set_attendees(friends);
        beerParty.set_startDateAndTime(new Date(2010,7,23,19,0,0));
        beerParty.set_priority(Priority.High());

        return beerParty;
    }

    public void Run() throws CloneNotSupportedException {

        CalendarEvent beerParty = getExistingEvent();

        CalendarEvent nextFridayEvent = (CalendarEvent) beerParty.clone();

        nextFridayEvent.set_startDateAndTime(new Date(2010,7,30,19,0,0));


        // we will talk about further code a bit later

        nextFridayEvent.get_attendees().get(0).EmailAddress = “andriybuday@liamg.com”;
        nextFridayEvent.get_priority().setPriorityValue(0);      
       
        if(beerParty.get_attendees() != nextFridayEvent.get_attendees())
        {
            System.out.println(“GOOD: Each event has own list of attendees.”);
        }
        if(beerParty.get_attendees().get(0).EmailAddress == nextFridayEvent.get_attendees().get(0).EmailAddress)
        {
            //In this case it is good to have shallow copy of the attendees.
            System.out.println(“GOOD: If I updated my e-mail address it will be updated in all events.”);
        }
        if(beerParty.get_priority().isHigh() != nextFridayEvent.get_priority().isHigh())
        {
            System.out.println(“GOOD: Each event should have own priority object, fully-copied.”);
        }
    }
}

As you can see my friend got copy of the existing event and by grag-drop changed its date. But after that I noticed that I can change my address in his attendees list, so I did that, also after we got another beer and felt sick we decided to lower priority to neutral with this line: nextFridayEvent.get_priority().setPriorityValue(0);

Looks like we’ve got what we want – copy of the existing event, with attendees, priority, etc. But it turns out that when I open old event I see that priority is now neutral, not high. As you already guessed that is because we executed shallow copy.

Shallow copy copies only direct value field and keeps same references.
Deep copy copies whole graph of objects, so they all have different addresses in heap.

CLONE

For Prototype we can implement clone() our own way, so for example I can have partially deep copy, so my new address should be the same in all events, but priority should keep different.

In Prototype design pattern we implement clone method. Sometimes we may need complete deep copy which can be archived by manual copying which is cumbersome, by reflection, which could be slow, or by serializing and deserializing to new object, which is also expensive. But sometimes you need partial deep copying like in our example. That is why programming languages introduces Cloneable interfaces to be implemented by our own. Suitalbe for our example could look like:

    @Override
    public CalendarPrototype clone() throws CloneNotSupportedException {
        CalendarEvent copy = (CalendarEvent)super.clone();
       
        // this allows us have another list, but same attendees there
        ArrayList<Attendee> copiedAttendees = (ArrayList<Attendee>) this.get_attendees().clone();
        copy.set_attendees(copiedAttendees);

        // we also would like to copy priority
        copy.set_priority(this.get_priority().clone());

        return copy;
    }

   
I already wrote console outputs that say we are ok. But also here is screenshot from debug mode to prove that I do not cheat:

Hope this article wasn’t boring and brought more understanding of Prototype design pattern. Please let me know what you think about it!


Here is my Design Patterns Table.


1 comment


Moving C# code to Java

May 9, 2010 C#, Java, MasterDiploma, Opinion 4 comments

Is CLR worse than JVM or it is just because my code is bad?

Today I had conversation with one man, who is great defender and evangelist of Java related technologies.

We talked about some algorithm implemented by me with C#. That is implementation of SOM algorithm and Concurrency stuff for it. My concurrency implementation doesn’t show time improvements unless grid size is big. He was able to achive better result with small grid sizes.

There could mean two reasons:

  • CLR concurrency model gives up in front of JVM concurrency
  • My implementation has gaps… which is more likely :)

Taking into consideration that I’m getting better results when grid is of bigger sizes I could suppose that in my algorithm there is code which takes constant (or near that) time and is not paralleled.

When I look at picture of Task Manager when my programm is executing I see that second processor has  gaps when it does nothing:

This could mean only one: I need to take better look what else is executed in one thread in my application and could be paralleled.

Converting C# code to Java

But back to that man and Java. I said to myself that it is possible to move my code to Java if something.

C# to Java Converter

Download C# to Java Converter demo version from here. Since it is demo you could not convert more than 1000 lines of your code. Order costs 119$.
Because of that I was forced to remove all not necessary code. I removed all concrete classes that I’m not using and GUI, but that did not help. I did not know how much should I delete more.

Number of lines in my project/solution

I googled for line numbers in C# and found this nice tool:

Now I know that my program has about 4000 lines of code. I left about 980 lines of code in two projects that I needed and was porting them to Java separately.

Converter GUI

And converted them to Java:

Is conversion an easy task?

Conversion could be painful if you have a lot of code that interacts with system, like threads, reading and writing to files, reading configuration file, etc.

Also it was not able to recognize ‘var’ keyword. It shows me this:

//C#
TO JAVA CONVERTER TODO TASK: There is no equivalent to implicit typing
in Java:

var neuronsCount =
getNetwork().getNeurons().size();

I moved back to my C# code and changed all var to the explicit types. And regenerated Java code.

There were some troubles when I’m delivering from List<T> and doing some stuff around that.
This code:

                int a =
this[next];
                this[next] = this[i];
                this[i] = a;

I rewrote manually to:

                int a =
super.get(next);
                super.set(next, super.get(i));
                super.set(i, a);

Also Converter was not able to convert this:

Console.ReadKey();

The biggest challenge is ThreadPool and synchronizing threads tech-nicks. This requires lot of google search that shows me that instead of ManualResetEvent I could use CyclicBarrier and how to utilize thread queuing in Java.

P/S I need to find gaps in my code to show that at least CLR and myself are not so much bad things in this world :)


4 comments


C# is language for my Diploma. It just won. What could I do?

February 21, 2010 C#, Java, MasterDiploma 2 comments

Today I committed initial version of my Diploma Work Sources.

And there are few interesting things regarding to my first commit.

Thing One (Language)

I re-wrote all my last year course work from Java to C#.
And I did it all in about 12 hours. Its just amazing how my developing speed differs in eclipse and Visual Studio IDEs. As I remember same took me 50+ hours with Java + eclipse and I did all without enthusiasm.

I hate writing properties in Java
This is one thing where I do think that Java is kind more verbose than C#. There are some others, like “var”, etc. Microsoft works on improving C# language.

C#

   public double[] Parameters {get; set;}
Java

    private double[] parameters;
    public double[] getParamateres(){
        return parameters;
    }
    public void setParamateres(){
        return parameters;

    }


How important is your knowledge of IDE?

I would say that even more then knowing of language. Nowadays most of  the languages are object-oriented, they all have similar principles and ideas and code looks almost the same. If we talk about C# and Java they are extremely alike.
I’m not very familiar with Java, but I can write Java code easily and if there are some Java specific gaps I quickly fulfill them with google search.
But when we talk about my speed of coding in eclipse IDE – it is really outstanding thing where my capabilities suck.

Code refactoring tool
That is another thing that could significantly increase your productivity. I’m using Resharper 5.0 Beta. Having experience of using it, I can think about what I want to have, but not how to type that.
Live templates that generates me unit test method after I just type “test”. Delivering from interface, I just created, without typing class name. Moving initialization of fields to the class constructor with single command. “Alt+Enter” just thing instead of me in contest of where mouse cursor is located and proposes me decisions.  — these all are things why I love Resharper. I wrote complex architecture with about 40 classes in about 12 hours. It generates what I think.

Thing Two (Architecture)


I improved my Self-Organizing Maps implementation architecture significantly. What is did is having all implemented in really decoupled interfaces. Main learning processor is just like preparing dinner. You just add component and you do have what you want.

        public LearningProcessorBase(
            ILearningData learningData,
            INetwork network,
            ITopology topology,
            IMetricFunction metricFunction,
            ILearningFactorFunction learningFactorFunction,
            INeighbourhoodFunction neighbourhoodFunction,
            int maxIterationsCount)
        {
            LearningData = learningData;
            Network = network;
            Topology = topology;
            MetricFunction = metricFunction;
            LearningFactorFunction = learningFactorFunction;
            NeighbourhoodFunction = neighbourhoodFunction;
            MaxIterationsCount = maxIterationsCount;
        }

What is the benefit?
Now I’m able easily setup few dependency Profiles and experiment with them. So I can play with different activation, neigbourhood, metric and leaning factor functions, at the same time I can use different topologies like matrix and hexagonal.
Also learning process is now really encapsulated and to add Concurrency implementation should be easily.

Thing Three (I have same results with less effort)

To prove that I have same results I’ve used same application of my Kohonen Maps: classification of animals.
Here is input data list of different animals. Each row describes animal’s properties.

Here is result matrix:

Thing Four (Conclusion)

I’m  really sorry that it is boring for me to have my Diploma written on Java. But I really think that my goal is to invent multi-threaded algorithm that could significantly improve SOM calculations. And I feel really comfortable with C#, so I can enjoy research work without spending time on convincing myself that I do need to accomplish all with Java.
But this doesn’t mean that I gave up with learning Java. No – I will continue implementing all GoF Design Patterns on this pretty language – see my table.


2 comments


Builder

January 29, 2010 Design Patterns, Java No comments

Imagine that you have shop where your Customers could buy Laptops with configuration they prefer. You need to develop system which will allow you easily build any configuration of Laptop for any User.
How could you easily accomplish this?

BUILDER

Builder is Creational Design Patter which allows you build some whole Product (Laptop) by constructing together some parts like Processor, Memory, Monitor, HDD, Battery and so on.
So your employee talks to Customer and asks questions which memory do you want and so on. Or otherwise if Customer is not technic, employee could ask “Do you need this laptop for gaming?”.
So you need some steps to construct you computer and they are defined in Abstract Builder.

Code:

/** Abstract Builder */
public abstract class LaptopBuilder {
    protected Laptop laptop;
   
    public void createNewLaptop(){
        laptop = new Laptop();
    }

    public Laptop getMyLaptop(){
        return laptop;
    }
    //mentioned steps to build laptop
    public abstract void setMonitorResolution();
    public abstract void setProcessor();
    public abstract void setMemory();
    public abstract void setHDD();
    public abstract void setBattery();
}

 If your Customer answers like “Yes, I wanna play… play…!!!“. You already have implementation of Concrete Builder for gaming laptop like:

/** Concrete Builder */
public class GamingLaptopBuilder extends LaptopBuilder {
    public void setBattery() {
        laptop.Battery = “6 lbs”;
    }
    public void setHDD() {
        laptop.HDD = “500 Gb”;
    }
    public void setMemory() {
       laptop.Memory = “6144 Mb”;  
    }
    public void setMonitorResolution() {
        laptop.MonitorResolution = “1900X1200”;
    }
    public void setProcessor() {
        laptop.Processor = “Core 2 Duo, 3.2 GHz”;
    }
}

Or if you Customer is business guy and he watches presentations and exel reports in plain:

Code:

/** Concrete Builder */
public class TripLaptopBuilder extends LaptopBuilder {
    public void setBattery() {
        laptop.Battery = “12 lbs”;
    }
    public void setHDD() {
        laptop.HDD = “250 Gb”;
    }
    public void setMemory() {
       laptop.Memory = “2048 Mb”;
    }
    public void setMonitorResolution() {
        laptop.MonitorResolution = “1200X800”;
    }
    public void setProcessor() {
        laptop.Processor = “Celeron 2 GHz”;
    }
}

To manage steps to build your Laptop basing on the answer you need Director:

Code:

/** Director */
public class BuyLaptop {
    private LaptopBuilder laptopBuilder;
   
    public void setLaptopBuilder(LaptopBuilder lBuilder){
        laptopBuilder = lBuilder;
    }
   
    public Laptop getLaptop(){
        return laptopBuilder.getMyLaptop();
    }
   
    public void constructLaptop(){
       
        laptopBuilder.createNewLaptop();
       
        laptopBuilder.setMonitorResolution();
        laptopBuilder.setProcessor();
        laptopBuilder.setMemory();
        laptopBuilder.setHDD();
        laptopBuilder.setBattery();
    }
}

Here we have usage code.

//Your system could have bulk of builders
TripLaptopBuilder tripBuilder = new TripLaptopBuilder();
GamingLaptopBuilder gamingBuilder = new GamingLaptopBuilder();

BuyLaptop shopForYou = new BuyLaptop();//director

shopForYou.setLaptopBuilder(gamingBuilder);//Customer answered that he wants to play
shopForYou.constructLaptop();

Laptop laptop = shopForYou.getLaptop();//just get what he wants
laptop.print();

Output:

Laptop: 1900X1200, Core 2 Duo, 3.2 GHz, 6144 Mb, 500 Gb, 6 lbs

Easy, simple and great pattern. 

What have I learned regarding of Java?
Nothing special, just how to format strings:

Code:

System.out.print(String.format(“Laptop: %s, %s, %s, %s, %s”, MonitorResolution, Processor, Memory, HDD, Battery));


No comments


FlyWeight

January 17, 2010 Design Patterns, Java 10 comments

Imagine that you are developing some gaming software. Your write Web client and on each of response you are parsing entire XML to get your game Units. You have some set of types of Units, for example 50 different animals, but when you parse your XML you can get dozens of instances of the same Unit and few dozens of instances of other Unit.
If User of the game is very passionate gamer, he could send requests very frequently. In this case your application will be creating dozens of instances for each of the Unit. But, your units have some static descriptions. For example, Dragon has Attack, initial Health level, and also you need to keep image of the dragon in the object of Dragon.

This all lead to intensive and not efficient memory usage. How could you share common information for all types of Units without creating instances for each individual Unit?

FLYWEIGHT

1) Simplest way with creating objects each time.

We have base class Unit:
 

public class Unit {
    protected String name;
    protected int health;
    protected String picture;
   
    public void setName(String name) {
    this.name = name;
    }
    public String getName() {
    return name;
    }
    public void setHealth(int health) {
    this.health = health;
    }
    public int getHealth() {
    return health;
    }
    public void setPicture(String picture) {
    this.picture = picture;
    }
    public String getPicture() {
    return picture;
    }
}

 
And two derived – Dog and Dragon. To make those objects more weightfull I added to them picture. In my case that is only very long string.

public class Dog extends Unit{
    public Dog(){
        name = “dog”;
        health = 30;
       
        for(int i = 0; i < 100; ++i)
            picture += “I
don’t want to load actuall image, but if we will be creating a lot of
strings on each of the Unit this could be very resrouce taking
operation.”
;
    }
}


And our parser executes code which looks like:

public class Parser {
    public ArrayList<Unit> parse(){
   
    ArrayList<Unit> result = new ArrayList<Unit>();

    for(int i = 0; i < 150; ++i)
        result.add(new Dragon());
   
    for(int i = 0; i < 600; ++i)
        result.add(new Dog());
   
    System.out.println(“Dogs and Dragons are parsed.”);
   
    return result;
    }
}

We want to create only 150 Dragons and 600 Dogs and this takes 28 Mb of memory.

2) How does FlyWeight work?

Lets introduce UnitsFactory. Responsibility of this factory is to manage creation of the concrete flyweight objects (Dogs and Dragons). It verifies if the object has been already created and in this case it just returns created and if not it creates new one and returns it. See:

public class UnitsFactory {
   
    private static Map<Class, Unit> _units = new WeakHashMap<Class, Unit>();
       
    public static Dog createDog(){
    Class dogClass = Dog.class;
   
    if(! _units.containsKey(dogClass))
        _units.put(dogClass, new Dog());
   
    return (Dog) _units.get(dogClass);
    }
   
    public static Dragon createDragon(){
    Class dragonClass = Dragon.class;
   
    if(! _units.containsKey(dragonClass))
        _units.put(dragonClass, new Dragon());
   
    return (Dragon) _units.get(dragonClass);   
    }
}

Lets take a look on UML diagram of our code:

UnitsFactory corresponds to FlyweightFactory, Unit – for Flyweight. Dog, Dragon corresponds to concrete Flyweights in the GoF FlyWeithgt naming.

Now we will do change to our parser to use Factory and will see how much of memory will it take.
But now we are going to create 1500 Dragons and 60000 Dogs, probably your gamer is quite more quick as you think.

    for(int i = 0; i < 1500; ++i)
        result.add(UnitsFactory.createDragon());
   
    for(int i = 0; i < 60000; ++i)
        result.add(UnitsFactory.createDog());
 

       
And this takes only about 5 Mb of memory:

What have I learned regarding to of Java?
I know that corresponding to C# Dictionary is Map in Java, and there are few concrete maps like on this good picture:

Hope this was a good story!

Go to: My Design Patterns Table 


10 comments


State

January 16, 2010 Design Patterns, Java 2 comments

Imagine that you need to develop application for shipping Orders. Your Orders could be in few states: New Order, Registered, Granted, Shipped, Invoiced, Cancelled.
And there are some rules which allow your Order to migrate to another state. This means that for example you cannot ship not registered Order.
Also there are some behavioral rules. For example you cannot add new Product to your Order when it is in Cancelled state. Also behavioral rules could mean changes in state.

How could you accomplish this requirements easily?

STATE
Allowable states
To be more clear about the behavior of our Order, lets take a look on the next statechart diagram:

We could encapsulate behavior which belongs to current object’s state into separate classes derived from some parent class. Each of the concrete will be responsible for allowing changing state from one to another.

State Pattern UML

State Pattern UML in application to Order problem

Order State

How does it work?

At first our Order class has a reference to its _state, to have more real example Order also has _products.

public class Order {

private OrderState _state;
private List<Product> _products = new ArrayList<Product>();

public void setOrderState(OrderState state){
     _state = state;
}

Order delegates some state-specific requests to the current state.

public void ship(){
    _state.ship();
}

 – If the current state is Granted, it changes Order‘s state to Shipped and if needed do some surrounded work or delegates it.

This code represents concrete implementation of the OrderState. Constructor of base class has Order parameter, so this allows us have reference to holding Order: _order in derived classes.

public class Granted extends OrderState{

    public Granted(Order holdingOrder) {
        super(holdingOrder);
    }

    public void ship(){
        _order.doShipping();
        //next line changes Order’s state
        _order.setOrderState(new Shipped(_order));
    }

If you are care what method ship() is doing in Order class it could be like shipping :).

public void doShipping(){
    System.out.println(“Shipping…”);
}

 – If current state is Registered, most likely that class has no implementation of method ship(), it has only addProduct(), grant(), and cancel(). So method of super class will be called. OrderState has all bulk of methods but they all throw exceptions, which says that changing state in current situation is not allowed.

public class OrderState {

    protected Order _order;

    public OrderState(Order holdingOrder){
        _order = holdingOrder;
    }
   
    public void ship(){
        raiseNotAllowableOperation(“ship”);
    }
    
    //other methods like register(), grant(), etc… here.. 
    //they look like the ship() looks

   
    private void raiseNotAllowableOperation(String operation) throws IllegalStateException {
        String stateName = this.getClass().getName();
        System.out.println(“ERROR: Operation [“+operation+“] is not allowed for current order state: “ + stateName);
        //of course in real system you will probably throw exception
        //throw new IllegalStateException(“This operation is not allowed for current order state.”);
    }

Example of Usage of Order class

Now we navigating to customer code. Our OrderingSystem creates new Order, adds some beer as product and all in correct way:

public void doHardWork(){
    Product beer = new Product();
    beer.Name = “Lvivske”;
    beer.Price = 78000;
   
    Order order = new Order();
    order.printStateName();
    order.addProduct(beer);
    order.printStateName();
   
    order.register();  
    order.printStateName();
   
    order.grant(); 
    order.printStateName();
   
    order.ship();  
    order.printStateName();
   
    order.invoice();   
    order.printStateName();
}

Output:

Order state: designpatterns.state.NewOrder
Product addeding calculation…
Order state: designpatterns.state.NewOrder
Registration…
Order state: designpatterns.state.Registered
Granting…
Order state: designpatterns.state.Granted
Shipping…
Order state: designpatterns.state.Shipped
Invoicing…
Order state: designpatterns.state.Invoiced

Ok, now we added code, which tries to add more beer when order has been already shipped.

    order.ship();  
    order.printStateName();
   
    //trying to add more beer to already shipped order
    order.addProduct(beer);
    order.printStateName();

Output:

Order state: designpatterns.state.NewOrder
Product addeding calculation…
Order state: designpatterns.state.NewOrder
Registration…
Order state: designpatterns.state.Registered
Granting…
Order state: designpatterns.state.Granted
Shipping…
Order state: designpatterns.state.Shipped
ERROR: Operation [addProduct] is not allowed for current order state: designpatterns.state.Shipped

Other ways to solve problem without State Pattern

One of the disadvantages of this you could see many of the classes needed to have:

Yes, but this is the way to greatly encapsulate your behavior. Also there are other ways to resolve problem. For example usage of the table [state|method|state] which is populated with all allowable transitions. You could also resolve issue with having switch-case method. About all of this you could read in Jimmy Nilsson’s book “Applying Domain-Driven Design and Patterns“.

What have I learned?

  • Java has no “virtual” keyword, that is because all methods are virtual. Make sense, cause in C# it is often needed to write huge amount of that word.
  • I discovered few Exceptions that Java has, for example IllegalStateException.
  • I was not able to easily figure out what to use instead of “:” in declaration of derived classed. Now I know “extends“.
  • I improved my UML skills with practicing drawing them.

I hope you enjoyed this story.

Go to: My Design Patterns Table


2 comments