user969729
user969729

Reputation: 299

Java Constructors or new class

Hey I am new java so forgive me if what I am about to ask is obvious, but I will try to explain as best as I can.

Its just a project that has been set for university so its not in a serious manner.

I have a class called MarsRoom which holds the attributes say for all the dimensions of the room like the totalheight and width of the walls in order to calculate the heat loss that the room will suffer in order to adjust the amount of solar energy that is needed to keep the room at the room temperature set.

The problem I am having is what is better practice or solution, to pass the attributes of the size of the room in a constructor(but this could get quite long in size, as the ones below are not only the ones that I may need) or create a whole different class specifically for that room like ROOM TYPE U? and set the attributes in there.

As it stands I can create a whole new room just by instantiating the room with the new values, but its going to get a little long, whereas I would rather not create a whole new class for a different room which may only differ from another room by a few meters on one of the walls!.

So what I am really trying to get at it, is is it ok to pass that many attributes to the constructor on instantiation?

//the instantiation in the runnable
MarsRoom room1 = new MarsRoom("RoomU", 40, 40, 20, 20, 8, 2, 4);

//the constructor in the MarsRoom class
public MarsRoom(String roomname, int windowsH, int windowsW, int wallsH, int wallsW, int windowC, int heaters, int lights){
    name = roomname;
    TotalWindowHeight = windowsH;
    TotalWindowWidth = windowsW;
    TotalWallHeight = wallsH;
    TotalWallWidth = wallsW;
    windowCeiling = windowC;
    numheaters = heaters;
    numlights = lights; 
    roomheaters = new Heaters[numheaters];
}

Upvotes: 1

Views: 212

Answers (8)

GeoGriffin
GeoGriffin

Reputation: 1095

You don't show what the fields of MarsRoom are, but for each feature, I would have a Collection of sub-objects. A MarsRoom has-a List of Windows. A MarsRoom has-a List of Walls. etc... Then have setters and getters for each and methods to add new instances of these features.

Since this is for school, I'm only including a little bit of pseudo code.

 public class MarsWindow {
    int     height;
    int     length;

    // Setters & Getters
    // standard getters & setters go here

    int getArea() {
        return this.height * this.width;
    }
}

public class MarsRoom {
    List<MarsWindow>   windows;
    List<MarsWall>     walls;
    List<MarsLight>    lights;
    List<MarsHeater>   heaters;

    public List<MarsWindow> addWindow(MarsWindow window) {
        // Add a window to the "windows" list here
    }

    public List<MarsWall> addWall(MarsWall wall) {
        // Add a wall to the "walls" list here
    }

    // Do this for the other fields

    int getTotalWindowArea() {
        int area = 0;
        // Iterate over all windows
        for(MarsWindow window : windows) {
            area += window.getArea();
        }
        return area;
    }

    // Add other calculation methods here

}

Upvotes: 1

Michał Kosmulski
Michał Kosmulski

Reputation: 10020

While technically legal, constructors with very long argument lists may be inconvenient to use. It also depends on whether you this the list may grow in the future or in subclasses.

If you have many parameters, but they have defaults and sometimes only a few need to be changed, you may find the Builder pattern useful. The idea is to replace constructor arguments with function calls, and allow them to be chained, for example:

public MarsRoom() {
    //empty or just basic stuff set here
}

public MarsRoom setTotalWindowHeight(int TotalWindowHeight) {
    this.TotalWindowHeight = TotalWindowHeight;
    return this;
}

public MarsRoom setTotalWindowWidth(int TotalWindowWidth) {
    this.TotalWindowWidth = TotalWindowWidth;
    return this;
}

...

then, you can call:

MarsRoom room1 = new MarsRoom()
    .setTotalWindowHeight(20)
    .setTotalWindowWidth(40);

Of course, if you wanted to set all parameters this way, it's longer (thou maybe more readable) than the single constructor. But if you only set 2 parameters out of 10, it will usually be more convenient.

Upvotes: 1

Sajan Chandran
Sajan Chandran

Reputation: 11487

Its always better to work with objects rather than primitives, you could use factory to create objects.

    //the constructor in the MarsRoom class
public MarsRoom(String roomname, WindowDimension windowDimension, WallsDimensions wallDimension, RoomAmbience ambience){
    }

    public class WindowDimension{
 private int height; //int windowsH
 private int width; //int windowsW
 private int circumference; //assumed windowC is circumference
}

public class WallsDimension{
 private int height; //int wallsH
 private int width; //int wallsW
}

public class RoomAmbience{
    private int heaters;
    private int lights;
}

Upvotes: 0

Isaac
Isaac

Reputation: 2721

Create a map with the keys being

Map<String, Integer> map = new HashMap();
map.put("TotalWindowHeight", new Integer(10));
map.put("TotalWindowWidth", new Integer(5));
...
map.put("NumberOfHeaters", new Integer(3));

MarsRoom room1 = new MarsRoom("RoomU", map);

Constructor will be like:

public MarsRoom(String roomname, HashMap<String, Integer> params) {
    name = roomname;
    TotalWindowHeight = map.get("TotalWindowHeight").intValue();
    TotalWindowWidth = map.get("TotalWindowWidth").intValue;
    ...
    roomheaters = new Heaters[map.get("NumberOfHeaters").intValue()];
}

this is not good OO however, but it seems like you are looking for something quick. If you want good OO you need to create an object for Window and in it you have hieght and width, another for ceiling, and you should not have number of something as a field, you should have an array to store the heater objects, and so and so forth, but this is quick and meets your requirement.

Upvotes: 1

Dan675
Dan675

Reputation: 1767

You could also use some polymorphism or have different types of rooms or something similar to this and then have a superclass with the common values that all rooms will have.

You can also have more than one constructor and have different ones for values you wish to set depending on the room type etc.

Upvotes: 0

calebds
calebds

Reputation: 26238

One of the great benefits object oriented programming is the possibility of not repeating yourself in code. Hence objects, which define data (members) and functionality (methods), and no requirement to create instances of these "prototypes" with hard values until run-time. To create a new class for each room when it

may only differ from another room by a few meters on one of the walls

would be to deny OOP (and Java) by gross repetition. I'd stick with the constructors, and if similar kinds of rooms end up emerging, try one of the static factory methods suggested, or break up common functionality using inheritanceOracle.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198471

I'd say that you should be adding factory methods here.

Basically, keep your constructor, but add methods like

static Room createLaundryRoom(laundryRoomParameters) {
  return new Room(...laundry room parameters plus defaults
    common to all laundry rooms...);
}

Upvotes: 2

Taymon
Taymon

Reputation: 25686

If what you're trying to do is simply not duplicate the parameters you're passing the constructor, you can simply put them in a separate static method, like so:

public static MarsRoom newRoomU() {
    return new MarsRoom("RoomU", 40, 40, 20, 20, 8, 2, 4);
}

Upvotes: 0

Related Questions