Results 1 to 20 of 20
  1. #1
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Please help with Singleton pattern.

    Java Code:
    Here is my code:
    
    public abstract class State {
    	public State stateObject;
    	abstract State getStateObject();
    }
    
    package myStatePatternExample;
    
    public class ConcreteStateA extends State {
    	@Override
    	State getStateObject() {
    		if(stateObject == null) {
    			stateObject = new ConcreteStateA();
    		}
    		return stateObject;
    	}
    }
    
    package myStatePatternExample;
    
    public class ConcreteStateB extends State {
    
    	@Override
    	State getStateObject() {
    		if(stateObject == null) {
    			stateObject = new ConcreteStateB();
    		}
    		return stateObject;
    	}
    }
    
    package myStatePatternExample;
    
    public class Machine {
    
    	State currentState;
    	State concA;
    	State concB;
    	
    	int value;
    	
    	
    	public Machine() {
    		concA = ConcreteStateA.getStateObject();
    		concB = ConcreteStateB.getStateObject();
    		currentState = concA;
    	}
    	
    	public void setValue(int value) {
    		this.value = value;
    	}
    }
    
    package myStatePatternExample;
    
    public class MachineA extends Machine {
    
    }
    
    public class TestClass {
    
    	public static void main(String[] args) {
    		
    		Machine machineA = new MachineA();
    		Machine machineB = new MachineB();;
    	}
    }
    What I am trying to do is, create two Concrete State Object ( only 2, no more ) and different machines ( MachineA, MachineB ) can have references to these State objects.

    Think like concreteStateA being the machine in turned on state, and concreteStateB in turned off.

    But I do not want every machine to have a seperate cocnreteStateA object. They should share one. So both should point to the same concreteStateA object...

    When I try to compile what I have above, I get:

    Exception in thread "main" java.lang.Error: Unresolved compilation problems:
    Cannot make a static reference to the non-static method getStateObject() from the type ConcreteStateA
    Cannot make a static reference to the non-static method getStateObject() from the type ConcreteStateB

    at myStatePatternExample.Machine.<init>(Machine.java: 13)
    at myStatePatternExample.MachineA.<init>(MachineA.jav a:3)
    at myStatePatternExample.TestClass.main(TestClass.jav a:7)

    Those lines are:

    Machine machineA = new MachineA();
    public class MachineA extends Machine {
    concA = ConcreteStateA.getStateObject();


    I do not see any static references, can you please help ? Thank you.

  2. #2
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,435
    Blog Entries
    7
    Rep Power
    20

    Default Re: Please help with Singleton pattern.

    Your getStateObject() methods aren't static but you consider them as such in your Machine class. States are excellent candidates for enums (enum instantiations are singletons by definition).

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  3. #3
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    concA = ConcreteStateA.getStateObject();

    I do not see any static references, can you please help ? Thank you.
    You should know that:
    Java Code:
    MyObject.doSomething()
    is a static reference, and will only work if the method 'doSomething()' is declared static.

    Since its not, you should first instantiate a class object and then call the method, so the correct code would be:
    Java Code:
    MyObject myObj = new MyObject();
    myObj.doSomething(); //not a static reference

  4. #4
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    Thanks..

    I understand the reason, but I can't figure out how I can use only ONE state object that is shared by two machines.

    Confusing..

  5. #5
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    Use an Enum like Jos said

  6. #6
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    But I am trying to learn the pattern. I may want to add more States, or keep track of how many times machines have been turned on and off... I want to add some properties to Status objects.

  7. #7
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    Okay so you need to make your variable static for your code to compile. It should look something like this:

    Java Code:
    public class Singleton() {
    
      private Singleton() {
        
      }
    
      static Singleton singleton = null;
    
      static public Singleton getInstance() {
        if (singleton == null) {
          singleton = new Singleton();
        }
        return singleton;
      }
    
    }

  8. #8
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    Apparently, that is not thread-safe. But this is:

    Java Code:
    public class Singleton {
            // Private constructor prevents instantiation from other classes
            private Singleton() { }
     
            /**
            * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
            * or the first access to SingletonHolder.INSTANCE, not before.
            */
            private static class SingletonHolder { 
                    public static final Singleton instance = new Singleton();
            }
     
            public static Singleton getInstance() {
                    return SingletonHolder.instance;
            }
    }
    Taken from Singleton pattern - Wikipedia, the free encyclopedia

  9. #9
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    Yes thanks but the problem is I want to make it an abstract class and extend two classes like State A and State B.

    Should I make my abstract classes constructor private ?

    Sorry for asking questions over and over again but with one class I can figure out how to do it and I understand your implementation, but when it is two classes that extends an abstract class I get confused.

  10. #10
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    You can't instantiate an abstract class anyway, so making it private wont matter (the purpose was to prevent it from being instantiated other ways than through your method).

    Abstract Methods and Classes (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)


    If you want to make an abstract class, each subclass would need its own singleton, so you would have to declare that field in each subclass, but you could declare an abstract method which has to be overrided in each subclass. I don't think you'd need anything else declared in the abstract class?

  11. #11
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    Thanks.
    I was trying to prevent code repeat in subclasses.

    But I guess I can't use a private constructor in the super class..

    And each subclass will need to have its own field right?

    Like in class ConcreteStateA

    there has to be a ConcreteStateA concA, and if this references to a null object then a new ConcreteStateA object will be created and returned, if not then the existing will be returned.

    I can't have a State state in the abstract class because it has to be Static therefore it can't be used in the way I desire by subclasses.

    Thanks for your time and your effort. I will try to come up with a solution and post it here.

  12. #12
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default Re: Please help with Singleton pattern.

    Actually I'm wrong, I was thinking as if it was an interface (where all fields are constants i.e. static and final)

    "Unlike interfaces, abstract classes can contain fields that are not static and final"
    Abstract Methods and Classes (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)

    if you read about abstract classes you'd know how to design this

  13. #13
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    The problem is when I code like this in abstract class:

    Java Code:
    public abstract class State {
    	
    	private State() {};
    	
    	public static State stateObject;
    	
    	State getStateObject() {
    		if(stateObject==null) {
    			stateObject = new State();
    		}
    		return stateObject;
    	}
    }
    Compiler warns me that an abstract class can no be initialized.

    So I guess I need to make the State getStateObject() method abstract as well.

    And I can not share the public stateObject in the sub classes, because there will be different subclasses..

  14. #14
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    The method getStateObject must be static, and there is no way to put a static method in a Abstract Class I guess. Therefore, it looks like using an abstract class here is not possible ?

  15. #15
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,435
    Blog Entries
    7
    Rep Power
    20

    Default Re: Please help with Singleton pattern.

    Of course you can put a static method in an abstract class; you just can't make a static method an abstract method.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  16. #16
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    This is exteremly confusing :)

  17. #17
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    I want to extend classes from State.

    Here is what I am trying to do:

    Java Code:
    public abstract class State {
    	
    	private State() {};
    	
    	private static State stateObject;
    	
    	static State getStateObject() {
    		if(stateObject == null)
    			{
    				stateObject = new State();
    			}
    		return stateObject;
    	}
    }
    but because you can not instantiate class State, this does not work.

    As JosAh you said, if I make the getStateObject method abstract that does not work as well. So what do I do ?

  18. #18
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    This is the solution I came up with:

    Java Code:
    package myStatePatternExample;
    
    public interface State {
    	
    	void handle(Machine m);
    	
    }
    Java Code:
    package myStatePatternExample;
    
    public class Machine {
    
    	State offState;
    	State onState;
    	State currentState;
    	
    	public Machine() {
    		offState = OffState.getOffState();
    		onState = OnState.getOnState();
    		currentState = offState;
    	}
    	
    	public void handle() {
    		currentState.handle(this);
    	}
    	
    	public void printState() {
    		System.out.print(this);
    		System.out.println(this.currentState);
    	}
    }
    Java Code:
    package myStatePatternExample;
    
    public class ToastMachine extends Machine {
    	
    	@Override
    	public String toString() {
    		String machine = "This is a Toaster Machine";
    		return machine;
    	}
    }
    Java Code:
    package myStatePatternExample;
    
    public class KettleMachine extends Machine {
    	
    	@Override
    	public String toString() {
    		String machine = "This is a Kettle Machine";
    		return machine;
    	}
    }
    Java Code:
    package myStatePatternExample;
    
    public class OnState implements State {
    	
    	private OnState() {objectCounter++;}
    	
    	static int objectCounter;
    	static int handleCounter;
    		
    	private static OnState onState = null;
    	
    	public static OnState getOnState() {
    		if(onState == null) {
    			onState = new OnState();
    		}
    		return onState;
    	}
    
    	@Override
    	public void handle(Machine m) { 
    		System.out.println(m + " has been turned off now.");
    		m.currentState = m.offState;
    		handleCounter++;
    	}
    	
    	public String toString() {
    		String result = " and it is turned on right now.";
    		return result;
    	}
    
    }
    Java Code:
    package myStatePatternExample;
    
    import java.util.ArrayList;
    
    public class OffState implements State {
    	
    	private OffState() {objectCounter++;}
    	
    	static int objectCounter;
    	static int handleCounter;
    		
    	private static OffState offState = null;
    	
    	public static OffState getOffState() {
    		if(offState == null) {
    			offState = new OffState();
    		}
    		return offState;
    	}
    
    	@Override
    	public void handle(Machine m) {
    		System.out.println(m + " has been turned on now.");
    		m.currentState = m.onState;
    		handleCounter++;
    	}
    	
    	public String toString() {
    		String result = " and it is turned off right now.";
    		return result;
    	}
    }
    Java Code:
    package myStatePatternExample;
    
    public class TestClass {
    	public static void main(String[] args) {
    		
    		Machine myToaster = new ToastMachine();
    		Machine myKettle = new KettleMachine();
    
    		myToaster.printState();
    		myKettle.printState();
    		
    		myToaster.handle();
    		myKettle.handle();
    		
    		myToaster.handle();
    		myKettle.handle();
    		
    		myToaster.handle();
    		myToaster.handle();
    		
    		myToaster.handle();
    
    		
    		System.out.println("Machines have been turned on: " + OffState.handleCounter + " many times.");
    	}
    }
    The output is:
    This is a Toaster Machine and it is turned off right now.
    This is a Kettle Machine and it is turned off right now.
    This is a Toaster Machine has been turned on now.
    This is a Kettle Machine has been turned on now.
    This is a Toaster Machine has been turned off now.
    This is a Kettle Machine has been turned off now.
    This is a Toaster Machine has been turned on now.
    This is a Toaster Machine has been turned off now.
    This is a Toaster Machine has been turned on now.
    Machines have been turned on: 4 many times.


    There is a lot of code repetition but I wasn't able to come up with a better solution.

    So if I decide to add a new Machine, I am not in very big trouble.

    If I want to add a new State such as PluggedOffState, then it looks like I will need to make a lot of copy&paste...

    Any help, suggestion is highly appreciated.

    Thank you.
    Last edited by fatabass; 03-10-2012 at 06:52 PM.

  19. #19
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,435
    Blog Entries
    7
    Rep Power
    20

    Default Re: Please help with Singleton pattern.

    enums for the states of a machine? (also see my first reply)

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  20. #20
    fatabass is offline Senior Member
    Join Date
    Nov 2011
    Location
    Turkey
    Posts
    380
    Blog Entries
    24
    Rep Power
    3

    Default Re: Please help with Singleton pattern.

    How can I count how many times machines have been turned on and off with enums ?

Similar Threads

  1. Singleton Pattern
    By ShaileshRaj in forum Advanced Java
    Replies: 5
    Last Post: 02-29-2012, 04:52 PM
  2. singleton design pattern
    By ziaur25@gmail.com in forum Advanced Java
    Replies: 2
    Last Post: 02-25-2011, 08:28 PM
  3. using singleton pattern in java
    By anandjain1984 in forum New To Java
    Replies: 1
    Last Post: 12-16-2009, 02:57 PM
  4. Singleton Pattern
    By Java Tip in forum Java Tip
    Replies: 0
    Last Post: 01-24-2008, 03:21 PM
  5. singleton pattern
    By Peter in forum Advanced Java
    Replies: 1
    Last Post: 07-09-2007, 04:45 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •