School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 306,961 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,895 people online right now. Registration is fast and FREE... Join Now!




Design thoughts

 

Design thoughts

anirelles

3 Nov, 2009 - 09:38 AM
Post #1

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
Hi,

There is something I am often faced to when designing and I would like to have some feedbacks.

If for example I have an object Country and an object City, and I say that a country is composed
of cities. I can think of 3 possible design.

design 1

class Country {
private String countryName;
private List cities; //list with all cities of the country
}

class City {
private String cityName;
}

design 2


class Country {
private String countryName;
}

class City {
private String cityName;
private Country country; // country in wich the city is located
}

design 3


class Country {
private String countryName;
private List cities; //list with all cities of the country
}

class City {
private String cityName;
private Country country; // country in wich the city is located
}



What will you say? What are the pros and cos of each ones?

For example in design3 , can't we say that the DRY (don't repeat yourself) concept is broken when we want to know in wich country is located a city? We can have this information by the variable country from the class City but also by looping every cities of the application and then looping the variable cities to find the city we are looking for.

This post has been edited by anirelles: 3 Nov, 2009 - 09:57 AM

User is offlineProfile CardPM
+Quote Post


Aeternalis

RE: Design Thoughts

3 Nov, 2009 - 10:59 AM
Post #2

D.I.C Regular
***

Joined: 13 Jul, 2009
Posts: 273



Thanked: 25 times
My Contributions
The design is going to depend on the business case. If your application only needs to have access to which cities are in a specific country, then scenario one is correct and sufficient.

If your application needs to be able to identify the country a specific city is in, and has no need to know all the cities within a country, scenario two is sufficient.

If your application needs to be able to do both, find all the cities in a country and find a country that a specific city is in, scenario three would be an acceptable choice, but could also be handled in other ways.

The DRY concept isn't necessarily broken by using scenario three, because it is not shown that a collection of cities exists and is available to iterate.

Aet
User is offlineProfile CardPM
+Quote Post

anirelles

RE: Design Thoughts

3 Nov, 2009 - 11:26 AM
Post #3

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
QUOTE(Aeternalis @ 3 Nov, 2009 - 10:59 AM) *

If your application needs to be able to do both, find all the cities in a country and find a country that a specific city is in, scenario three would be an acceptable choice, but could also be handled in other ways.

The DRY concept isn't necessarily broken by using scenario three, because it is not shown that a collection of cities exists and is available to iterate.


Thanks. Let's say we are in this scenario. What are the others ways you are thinking about? I am interested in.
Instead of having a list of Cities in Country we could have a list of cities' ID but to me it's not a good OO design. Maybe I'm wrong.

The thing is that if I modify the name of a city I also have to modify the name of the same city in the Country class.

Maybe we can say that DRY principle is violated for performance reason in the scenario where we want to know in which country is located a city.
User is offlineProfile CardPM
+Quote Post

SixOfEleven

RE: Design Thoughts

3 Nov, 2009 - 01:31 PM
Post #4

Code Guru
Group Icon

Joined: 18 Oct, 2008
Posts: 3,050



Thanked: 169 times
Dream Kudos: 775
Expert In: C, C#, XNA, Game Programming, Programming Concepts

My Contributions
I would actually go with a cross between 1 and 3 for this personally. Something along the lines of this:

CODE

class Country {
    private String countryName;
    private List<City> cities; // C# syntax for a list of cities
    public addCity(City city);
    public removeCity(City city);
}

class City {
    private String cityName;
    private String countryName;
    public String getName();
    public void setName(string cityName);
    public String getCountry();
    public void setCountry(String countryName);
}


I would go with that. The reason I would is a Country should be able to work with the Cities that belong to it. A City should know what Country it belongs to but should never be allowed to do anything with that Country. It makes sense to me to have the name of the country as an attribute of City. This way you could say to a Country that City X has been renamed to City Y. The City would get a call from the Country class saying: "Hey, this is your name now." You could remove cities from a Country. The removing scenario could happen in a war. You could also easily add a new City to a Country.

I'm really liking this discussion. I would really like to read other people's ideas on this.
User is offlineProfile CardPM
+Quote Post

anirelles

RE: Design Thoughts

3 Nov, 2009 - 02:07 PM
Post #5

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
QUOTE(SixOfEleven @ 3 Nov, 2009 - 01:31 PM) *

A City should know what Country it belongs to but should never be allowed to do anything with that Country. It makes sense to me to have the name of the country as an attribute of City.


Imagine that later we want to know not only the name of the country but also the name of the president and the currency of the country, with your design we would have to add these attributes to the City class. Isn't it better to have a reference to a Country so we don't have to modify the code of City when specifications change?

User is offlineProfile CardPM
+Quote Post

SixOfEleven

RE: Design Thoughts

3 Nov, 2009 - 02:59 PM
Post #6

Code Guru
Group Icon

Joined: 18 Oct, 2008
Posts: 3,050



Thanked: 169 times
Dream Kudos: 775
Expert In: C, C#, XNA, Game Programming, Programming Concepts

My Contributions
QUOTE(anirelles @ 3 Nov, 2009 - 04:07 PM) *

Imagine that later we want to know not only the name of the country but also the name of the president and the currency of the country, with your design we would have to add these attributes to the City class. Isn't it better to have a reference to a Country so we don't have to modify the code of City when specifications change?


That is an excellent point. (I told you I'm enjoying this thread.) It would be a good idea to think of future versions of the program if the scope of the program were to change eventually down the road.

However, think of how your program is going to work. Would the main class the program works with be City or Country? In my opinion I would work in terms of Country. One reason is in this world there are several cities with the same name in different countries. There is, for example, London Canada and London England. If you were to say: What is the currency of London? Which London are you looking for? The way I would work it in the program is that you would work with countries. If the user wanted to know the currency of a city they would supply the country name and the city name. The program would first look for the country. It would then check the list of cities to see if there is a city of that name in the country. In this design a City would not be able to change anything in a Country

Your models two and three would be a case of dependency. The City class would depend on the Country class. It would, for example, have to get its currency, president, etc from the Country class. There would be coupling involved in this program. Some times you have to deal with coupling. Just try and minimize it. You would want to limit the public methods of the Country class though so that the City class could not change things in the Country class. For example, if you had a public method in the Country class called setLeader, which is reasonable because leaders change, a City would be able to change the leader of the whole country! That is not something you would want. You could implement a Clone interface and pass copies of the Country to the City and have both a List of City and a List of Country. This would also increase the memory used by the program.
User is offlineProfile CardPM
+Quote Post

cfoley

RE: Design Thoughts

3 Nov, 2009 - 03:54 PM
Post #7

D.I.C Addict
Group Icon

Joined: 11 Dec, 2007
Posts: 660



Thanked: 63 times
Dream Kudos: 25
My Contributions
I think a design flaw in 3 (and especially SixOfEleven's version of it) is that you could imagine a situation like the following:

CODE
Country scot = new Country("Scoltand");
City city = new City("Glasgow");
scot .add("Glasgow");
city.setCountry("England");


This is clearly wrong but the sata type allows it. Designs one and two might be slower for certain operations (i.e. needing a search) but you can guarantee you won't have an illogical state. Design three will be more efficient in run time but the developer has more opportunity to introduce bugs.

One option is to go with design three but reduce the visibility of the setCountry method in the City class. Depending on the language, make it package private or available only to friendly classes. That way, adding a city to a country will call setCountry automatically. Even better if setCountry throws an exception if it had been set previously.



This brings up another issue... the public interface to the whole thing. Now, what I'm about to suggest may be totally inappropriate to your project but you could have a third class World which has methods such as:

getCountry(String name)
getCity(String name)
getCitlesInCountry(Country c)
getCountryOfCity(City c)
... and so on

This way you can have a very well-defined public interface for your model and can have rigorous test code. Whatever internal representation you have for your countries and cities, you can change whenever you want as long as all the tests you write still pass.

Anyway, just my thoughts. smile.gif
User is offlineProfile CardPM
+Quote Post

SixOfEleven

RE: Design Thoughts

3 Nov, 2009 - 08:03 PM
Post #8

Code Guru
Group Icon

Joined: 18 Oct, 2008
Posts: 3,050



Thanked: 169 times
Dream Kudos: 775
Expert In: C, C#, XNA, Game Programming, Programming Concepts

My Contributions
Having a World class with a set of well defined public methods would be a good approach to this problem. Probably better than any of the other approaches discussed so far This is why it is good to work in teams with other programmers when you are working on analysis and design. Each team member brings a different perspective to problem.

About this code:

CODE

Country scot = new Country("Scoltand");
City city = new City("Glasgow");
scot .add("Glasgow");
city.setCountry("England");


Yes, that is definitely a bad thing. Much like the city being able to set the leader of a country. It is unlikely that you would ever need to set the country after creating the city. I was thinking of strategy games where the player captures an enemy city. In the real world it his highly unlikely that a single city would change countries. Like cfoley said the setCountry method could be access limited using packages/friends to the City and Country class. Meaning that only the Country or City class have access to that method and any other methods that would create a no-no.

There is, however, the case where countries separate or merge. Here in Canada there is a separatist movement where one province wants to separate from the rest of the country. If that was to happen how would you solve that problem? Also there is always the possibility that Northern Ireland and Southern Ireland, or North Korea and South Korea would merge.

With the World model with a well defined public interface those situations could easily be remedied. The best idea would be to create two new instances of Country for separation and divide the cities to the new countries. For the merging, create a new Country and add the cities from the old countries.

In any event you would definitely want to do a lot of validation and error checking with this type of program. The more I think about it the more I like the World class idea with a strongly defined public interface.
User is offlineProfile CardPM
+Quote Post

anirelles

RE: Design Thoughts

5 Nov, 2009 - 04:11 AM
Post #9

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
QUOTE(SixOfEleven @ 3 Nov, 2009 - 08:03 PM) *

In the real world it his highly unlikely that a single city would change countries.


What about Hong Kong ? wink2.gif

QUOTE

For example, if you had a public method in the Country class called setLeader, which is reasonable because leaders change, a City would be able to change the leader of the whole country! That is not something you would want.
You could implement a Clone interface and pass copies of the Country to the City

Good point. It is necessary to find a way to avoid City to have access of SetMethods of Country.

QUOTE

In any event you would definitely want to do a lot of validation and error checking with this type of program. The more I think about it the more I like the World class idea with a strongly defined public interface.


Brilliant. I can keep design 3 and rely on World class to manipulate Country and City correctly.

But I have to be very careful with the visibility of setters method to avoid that :

QUOTE

City city = World.getCity("Mexico");
city.setCountry("England");


This post has been edited by anirelles: 5 Nov, 2009 - 04:44 AM
User is offlineProfile CardPM
+Quote Post

anirelles

RE: Design Thoughts

5 Nov, 2009 - 04:37 AM
Post #10

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
So summing up. For my initial problem I can decide to use design3 admitting that I break DRY principle but for performance reason. And to minimize the risk of illegal state I introduce a new class (World) which is the unique place for creation and update of my objects.
Is there some design pattern which looks like that? Maybe we have figured out a new design pattern bananaman.gif

This post has been edited by anirelles: 5 Nov, 2009 - 04:49 AM
User is offlineProfile CardPM
+Quote Post

anirelles

RE: Design Thoughts

5 Nov, 2009 - 06:54 AM
Post #11

D.I.C Head
**

Joined: 1 Jan, 2009
Posts: 55



Thanked: 2 times
My Contributions
It's me again lol

I tried to code design 3 and World class and I would like to give feedbacks:

Here there is the code of World :

CODE

public class World {


    public static Country getCountry(String name){
        //read the country from database
        return new CountryImpl(name);
    }

    public static Country addCityToCountry(Country oldCountry, String newCityName){

        //new country is just the old country where we will add a new city
        CountryImpl newCountry = new CountryImpl(oldCountry.getName());

        //we create the city we want to add to the new country
        CityImpl newCity = new CityImpl(newCityName);
        newCity.setCountry(newCountry);

        //all cities of the old country must be part of the new country
        //and we make them point to the new country
        for (Object oldCountryCity : oldCountry.getCities()) {
            CityImpl city = (CityImpl)oldCountryCity;
            city.setCountry(newCountry);
            newCountry.addCity(city);
        }

        //finally we add the new city to the new country
        newCountry.addCity(newCity);
        return newCountry;

    }

    public static void saveCountry(){
        
    }

}


I have a Country interface :
CODE

public interface Country {

    String getName();
    List getCities();

}


and a City Interface :
CODE

public interface City {

    String getName();
    Country getCountry();

}


CityImpl class:

CODE

class CityImpl implements City {

    String name;
    Country country;

    public CityImpl(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Country getCountry() {
        return country;
    }

    void setCountry(Country country){
        this.country = country;
    }

}


CountryImpl class :

CODE

class CountryImpl implements Country{

    String name;
    List cities;


    public List getCities() {
        return cities;
    }
    
    public CountryImpl(String name){
        cities = new ArrayList();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    void addCity(City city){
        cities.add(city);
    }

}



My main program is :

CODE

public static void main(String[] args) {
        Country country = World.getCountry("France");
        country = World.addCityToCountry(country, "Nice");
        country = World.addCityToCountry(country, "Marseille");
            World.saveCountry(country);
    }


I'm not happy with World class, it's a lot of code for not so much.
Finally I changed my mind and the simple solution is like SixOfEleven said :

QUOTE

However, think of how your program is going to work. Would the main class the program works with be City or Country? In my opinion I would work in terms of Country.


I'll access the cities through Country so I just have to keep a reference to the Country in my main program
So it's design 1 I'll choose.

This post has been edited by anirelles: 5 Nov, 2009 - 07:16 AM
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/21/09 04:20AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month