tags:

views:

206

answers:

8

Hi All

I'm just starting to learn Java and I'm struggling to find the correct way to implement the following.

I have a Class called State. This Class has a field called stateCaptial.

I create a State object.

Then I want to create many Town objects that are linked to the one State object, If I query the town for its state capital it should get it from the state object. I think it would be classed as one to many object relationship ?

What is the Java terminology for implementing such a solution ?

Many Thanks Andy

A: 

Why not an array of towns in state, each referring back to the state they are in?

Michael Goldshteyn
+1  A: 

This would be a one to many relationship.

The best way to do this would be to have each Town object have a state field that refers to the State that it is part of. The getStateCapital method of Town would then get the stateCapital from its state and return that.

You would probably also want to have an array or List of Town objects on your State object so you could list all the Towns within a State.

Alan Geleynse
+1  A: 

What you are describing is that you would like your Town objects to be dependent on a State object. The act of inserting the dependent object into the Town class is commonly known as dependency injection or DI.

You would have a class structure similar to this

public class Town
{    
    private State _state;

    public Town(State state)
    {        
        _state = state;        
    }    

    public string StateCapital()
    {        
        return _state.Capital;
    }    

}
Chris Marisic
I'd probably have used a property instead of a method to get the state capital but I can't remember java properties vs c# properties anymore.
Chris Marisic
This has the minor caveat of only being a one-way relationship - he'd probably want to not only find a `State` through `Town`, but also all `Towns` within a `State`.
mway
You could make it a bidirectional association yes, however I've always found bidirectional associations to be very complex to work with and usually alter the relationship to make it unidirectional and provide alternative means to reach the complementary side of the relationship if it's actually needed. Many times bidirectional associations fall under YAGNI (you ain't gonna need it)
Chris Marisic
This example code is very C#. Method and field names with upper char, and underscores for private fields. Not a problem, just wanted to make it obvious for those just starting with Java.
Tom Castle
A: 

Hi

You should look into encapsulation, abstraction and probably inheritance.

You should try to think of each object that you create as encapsulating the data that directly related to it, and providing methods of accessing and operating on that data.

For this issue, you could create two classes, State and Town.

Your State class will have a member called Capital which will be of type town and a List called Towns which contains all the towns in it. The town class will have a member called state.

CrapHands
+1  A: 

You could create a a Town class as well. So, State has a field called capital of type Town. State also has a `Set' of towns so that all the towns can be looked up for a state. Town has a field state of type State. Something like below.

State class:

public class State {

     private Town capital;
     private Set<Town> towns;

     public State() {
       this.towns = new HashSet();
     }

     public State(Town capital) {
       this.capital = captial;
       this.towns = newHashSet();
       this.towns.add(capital)
     }


     public void setCapital(Town capital) {
       this.captial = capital;
     }

     public Town getCapital() {
       return this.capital;
     }

     public void addTown(Town town) {
       this.towns.add(town)
     }

     public Set getTowns() {
       return this.towns;
     }
}

Town class:

public class Town {

    private State state;

    public Town() {}

    public Town(State state) {
      this.state = state;
      this.state.addTown(this);
    }

    public void setState(State state) {
      this.state = state;
      this.state.addTown(this);
    }

    public State getState() {
      return this.state;
    }
}

Then if you have a Town object called myTown, to get the town's state's capital you use:

myTown.getState().getCapital();

If you have a State object called myState, you get all the town's you use:

myState.getTowns();

Owen
Is the interface for Town.getState() correct?
Huperniketes
@Huperniketes Nope - it wasn't. Copy and paste FAIL. I've updated it now. Town.getState() return type should be State.
Owen
I like it ! This seems the most in depth answer. Some of the others are mentioning Dependancy injection , is this solution a form of DI ? I eventually want to stick all the objects in DB. I'm tryin to start from the ground up the correct way - if you know what I mean.
AndyM
Truthfully, I'm not sure if this is "dependency injection" or not. If you're looking to eventually get this stuff to a database - I'd recommend reading about the Java Persistence API (JPA). http://www.oracle.com/technetwork/articles/javaee/jpa-137156.html
Owen
A: 

From an OOP point of view, that's what should be the correct implementation. I'm going to use C# syntax since I'm familiar with it, but it shouldn't be too different from java.

public class State
{
public string Name {get;set;}
public ICollection<City> Cities {get;set;} //Access to all child cities
}

public class City
{
public string Name {get;set;}
public string State_Name {get;set;} //this is sort of a FK
public State State {get;set;} //Direct access to the State object related
}

You could omit the string State_Name from the City class, as you can reach the same property by using city.State.Name; Anyway it could be very convenient to have the "FK" directly on the child class for some purposes. Of course in this case, you should have code that ensures that the FK stays syncronized with the State object. If these classes are used, let's say, by an ORM framework, usually this is handled automatically.

Matteo Mosca
Is this really java code? It's indistinguishable from C#.
Chris Marisic
-1 C# on java question
bwawok
@bwawok Oh my god, can people be really that dense? I guess so. Does syntax really matter? It's the concept the important thing. I clearly stated that I would use c# syntax because I'm familiar with it. I could have written pseudo-code for that matter, the concept applies regardless of the language. But I guess you're one of that "specific-language" fanboys who downrate anyone who mentions a language different than their beloved. I *THOUGHT* stackoverflow had a community of mature people but I was clearly wrong.
Matteo Mosca
How are you handling State Capital in this example?
Tester101
I disagree with a downvote in general for explaining with a different language, but there are significant differences that can make an impenetrable barrier between a Java newbie and C# code. Java doesn't have properties, e.g.
Mark Peters
If the OP asks for a java solution at the very worst case someone should provide pseudocode. That's the equivalent of saying you want English and I give you Dutch
Woot4Moo
I used C# not only because I'm familiar with it, but also because the syntax is very similar to java. Anyway, to handle the capital, one solution could be adding a boolean property "IsCapital" on the "City" class, and ensure a XOR between cities that share the same state.
Matteo Mosca
A: 

Aggregation and delegation..

Selim
+1  A: 

Here are my thoughts. The relationship is a one to many (State to Town) so to represent this in code it would look something like this:

public class State {
    private Set<Town> towns;

    public State() {
        // default constructor
    }

    public State(Set<Town> towns) {
        this.towns = towns;
    }

    public void createTown(Town town) {
        towns.add(town);
    }
}

Now the Town class could look something like this:

public class Town {
    private State state;
    private boolean isCapital;

    public Town() {
        // default constructor
    }

    public Town(State state) {
        this.state = state;
    }

    public void setCapital(boolean isCapital) {
        this.isCapital = isCapital;
    }
}
Woot4Moo