Setting an instance variable using dependency - java

I am working on a project where I am trying to represent a Stock Portfolio. There is a class called Position. Also, there is another class called Portfolio and it's basically represents a set of positions along with additional instance variables/methods.
A single Position is stored in a plain .txt file. In order to read that file, I've created another class: ReaderService. In this class, necessary I/O operations are being performed and in the end, a List<Position> is being returned by the method called readPositions().
Portfolio class depends on ReaderService in order to set its positions field, and I am injecting that dependency via constructor, that is constructor injection.
What I can't be sure about is that it seems like a bad practice to initialize a instance variable of Portfolio class in a setter method by using ReaderService dependency. Does this approach leads to any problems like tight coupling or smt else?
Here is the quick summary
ReaderService:
public class ReaderService {
// necessary fields..
// a method to extract all positions from the each line of .txt file.
public ArrayList<Position> readPositions(){
ArrayList<Position> positions = new ArrayList<>();
...
/* for each line in the file, a new `Position` is being created
and being added to `positions` after necessary file operations performed. */
...
// Initializing a new position and adding it to the list
Position position = new Position(...);
positions.add(position);
return positions;
}
}
Position class:
public class Position {
private String stockCode;
private double balance;
...
// There are more than two fields. Truncated it for the sake of the question.
public Position(String stockCode, double balance, ...) {
this.stockCode = stockCode;
this.balance = balance;
...
}
}
And the class in question; Portfolio class:
public class Portfolio {
private ArrayList<Position> positions;
...
private final DataService dataService;
private final ReaderService readerService;
public Portfolio(DataService dataService, ReaderService readerService){
this.dataService = dataService;
this.readerService = readerService;
}
public ArrayList<Position> getPositions() {
return positions;
}
// Check out this method. Is it a poor design?
public void setPositions() {
try {
this.positions = readerService.readPositions();
}
catch (IOException ex){
ex.printStackTrace();
}
}
}
Is it correct thing to question the following:
"A ReaderService is responsible to read the positions, but you are giving it the responsibility of creating list of positions for Portfolio class as well.'
I mean do I break the Single Responsibility principle here?
I am also considering to make these service classes static.

For the sake of readability, I answer here.
Rather than setPositions(), I would like to create with constructor. And create another class (or you can put it in main class as you said, but you may don't like it) as below.
public class PortfolioService {
private final DataService dataService;
private final ReaderService readerService;
public PortfolioService(DataService dataService, ReaderService readerService) {
this.dataService = dataService;
this.readerService = readerService;
}
public PortfolioService createPortfolio() {
return new Portfolio(readerService.readPositions());
}
}
then, Portfolio class will look like this.
public class Portfolio {
private final List<Position> positions;
public Portfolio(List<Position> positions) {
this.positions = positions;
}
// and do something else with positions
}

Related

So I am lost in creating classes, private/public variables, get/set functions, and more in Java

So this is the first part of my assignment:
Create a new java class called "House".
Add constructor without parameters and add a system out put of your choice
Add 4 Private Member Variables
an integer that represents the number of rooms
a String that represents the address
a boolean that represents if the house is for sale
a double that represents the value of the house
Add a Get and Set functions for ALL 4 member variables
In my house code I think this is the right way to do it:
public class House {
private int Rooms;
private String Address;
private double Value;
private boolean Sale;
public House() {
System.out.println("CONSTRUCTOR EXECUTED");
}
public void setRooms(int Rooms) {
this.Rooms = Rooms;
}
public int getRooms () {
return Rooms;
}
public void setAddress (String Address){
this.Address = Address;
}
public String getAddress() {
return Address;
}
public void getValue(double Value) {
this.Value = Value;
}
public double setValue() {
return Value;
}
public void getSale(boolean Sale) {
this.Sale = Sale;
}
public boolean getSale() {
return Sale;
}
}
For the second part, which I'm more confused about, is says this:
Create a Main Class and add the static main function
Initialize Main and add a start function
In the start function create new House object
Call all 4 Set functions
Output all 4 Get Functions
Example Output "The House has '4' rooms located at 'address' and is or is not for sale'
If the house is for sale, out the value of the house
So I created the Main file and I think I have the start up correct but I don't know how to print it all out. This is what I at least have so far:
public class Main {
public static void main(String[] arg) {
}
private void start() {
House rooms = new House ();
}
}
I definitely do not want the answer, just some pointers in the right direction.
Looking at the instructions, I don't think you need to create a separate Main class. I think when it says 'Initialize Main' it just means add the main method to the House class.
Additionally, the way you have it now is not going to work properly. start() will not be able to be called from the main method, since main is static and start is not.
My feeling is that the best way to go about it would be to put main and start in the House class. Then, you can initialize an instance of House in the main method, and then call start on that instance. From there, start can perform the rest of the instructions.
Hope this helps.

Getting Variables From Java constructor

I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.

Is it better to duplicate an object to store old values?

I have a page where I can edit an object's values in Java. However, I would need to store and pass the object's old values as well for the Stored Procedure.
For this, I duplicated the object like so:
public void onClickEdit(Education e) {
Education edOld = new Education(e);
Education edNew = new Education(e);
goToPage(a);
}
I also made it so that the user will only edit edNew in the edit page.
The Education class has a constructor that sets another Education class' attributes as its own, like so:
public class Education {
private int educationID;
private String educationName;
private String educationStatus;
public Education() { }
public Education(Education e) {
educationID = e.getEducationID();
educationName = e.getEducationName();
educationStatus = e.getEducationStatus();
}
// setter-getters ...
}
My question is, would it be better on the memory to have a single class that has attributes for new and old attributes - like this:
private int educationID;
private String educationName;
private String educationStatus;
private int old_educationID;
private String old_educationName;
private String old_educationStatus;
or is the way that I am doing it fine as well?

EnumSet doesn't think my enum is an enum [duplicate]

Error:
...
Caused by: java.lang.ExceptionInInitializerError
...
Caused by: java.lang.ClassCastException:
class com.evopulse.ds2150.TechTrees$BuildingTechTree
not an enum
at java.util.EnumSet.noneOf(Unknown Source)
at java.util.EnumSet.of(Unknown Source)
at com.evopulse.ds2150.TechTrees$BuildingTechTree.<clinit>(TechTrees.java:38)
Here is a snippet of my enumeration
public enum BuildingTechTree {
//Name SoftName Requirements
NONE ("NULL", null),
--> This next line is where it crashes
BARRACKS ("Barracks", EnumSet.of(NONE),
WALLS_SANDBAGS ("Sandbag wall", EnumSet.of(NONE),
POWERPLANT ("Power plant", EnumSet.of(BARRACKS)),
GUARDTOWER ("Guard Tower", EnumSet.of(BARRACKS));
Replacing EnumSet.of(NONE) and EnumSet.of(BARRACKS) with null, lets initialization work, but breaks my code, due to missing data structure... obviously, but I did it to test the rest of my code wasn't somehow the cause.
Removing EnumSet.of(NONE) and replacing with just NONE, and the same for BARRACKS, and changing all related variables, constructor, and methods, that didn't work either... (and even couldn't use the contains.all, since is wasn't "applicable to my changed variable"... )
I extended this example, using the second implementation:
https://gamedev.stackexchange.com/a/25652/48573
I also tried retracing my steps by copying the example verbatim. added
private static Set<BuildingTechTree> techsKnown;
techsKnown = (BuildingTechTree.BIODOME);
test = TechTrees.researchTech(techsKnown);
to another class to be called from for testing initialization. and had to change
public boolean researchTech(BuildingTechTree tech) {
to static
This resulted in the same "in not an enum" error. I don't have any rep, to comment on his answer to point out the initialization error...
Added info for both current answers, as both solutions cause the same new error:
public class TechTrees {
private static Set<BuildingTechTree> techsKnown;
public TechTrees() {
techsKnown = EnumSet.of(BuildingTechTree.NONE); //Using this
techsKnown = EnumSet.noneOf(BuildingTechTree.class); //Or this
}
public static boolean researchTech(BuildingTechTree tech) {
if (techsKnown.containsAll(tech.requirements)) { //Causes null pointer
return true; //exception # techsKnown
}
return false;
}
Your declaration structure is so clever it's a shame it doesn't work. But EnumSet apparently needs the enum to be fully initialized first. It tries to fetch the array of constants from the enum so that, among other things, it knows how much space is needed for its internal bitset.
Here's one workaround. It uses a helper method that creates an ordinary set (HashSet) first, and then, in a static initialization block, it iterates the enum constants and replaces all the sets with EnumSets.
public enum BuildingTechTree {
// Named constants
//Name SoftName Requirements
NONE ("NULL", null),
BARRACKS ("Barracks", setOf(NONE)),
WALLS_SANDBAGS ("Sandbag wall", setOf(NONE)),
POWERPLANT ("Power plant", setOf(BARRACKS)),
GUARDTOWER ("Guard Tower", setOf(BARRACKS));
private final String softName;
private Set<BuildingTechTree> requirements;
private BuildingTechTree(String softName, Set<BuildingTechTree> requirements) {
this.softName = softName;
this.requirements = requirements;
}
private static Set<BuildingTechTree> setOf(BuildingTechTree... values) {
return new HashSet<>(Arrays.asList(values));
}
static {
for (BuildingTechTree v : values()) {
if (v.requirements == null) {
v.requirements = EnumSet.noneOf(BuildingTechTree.class);
} else {
v.requirements = EnumSet.copyOf(v.requirements);
}
}
}
}
You have a chicken and egg problem. You could refactor your enum to something like this:
public enum BuildingTechTree {
NONE("NULL"),
BARRACKS("Barracks"),
WALLS_SANDBAGS("Sandbag wall"),
POWERPLANT("Power plant"),
GUARDTOWER("Guard Tower");
static {
NONE.trees = EnumSet.noneOf(BuildingTechTree.class);
BARRACKS.trees = EnumSet.of(NONE);
WALLS_SANDBAGS.trees = EnumSet.of(NONE);
POWERPLANT.trees = EnumSet.of(BARRACKS);
GUARDTOWER.trees = EnumSet.of(BARRACKS);
}
private String name;
private Set<BuildingTechTree> trees;
private BuildingTechTree(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Set<BuildingTechTree> getTrees() {
return Collections.unmodifiableSet(trees);
}
}
EDIT:
regarding your second problem: you're accessing a static variable, from a static method. But this variable is initialized when the constructor of the class has been called (which is a huge design problem). Don't use non-final static fields. And don't initialize static fields from instance methods or constructors. That doesn't make sense. You don't set the color that all cars should have when constructing a car. Initialize your static fields statically:
public class TechTrees {
private static final Set<BuildingTechTree> TECHS_KNOWN =
EnumSet.of(BuildingTechTree.NONE);
public static boolean researchTech(BuildingTechTree tech) {
return TECHS_KNOWN.containsAll(tech.requirements));
}
}

Any nice way to make two immutable objects refer to eachother?

Take these two Java classes:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.
Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.
(* Because reflection may give trouble with a security manager)
(** Says my limited knowledge)
This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!
Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.
Delving deeper into the issue, I foundĀ§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.
You can do it if you don't need to inject one of the objects.
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
class User {
private final Inventory inventory;
User (/*whatever additional args are needed to construct the inventory*/) {
//populate user fields
inventory = new Inventory(this);
}
}
class Inventory {
private final User owner;
Inventory (User own) {
owner = own;
}
}
That's the best I can think of. Maybe there's a better pattern.
Slightly pedantic, but it's not strictly speaking necessary to create one inside the other, if you don't mind a little indirection. They could both be inner classes.
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User() {
... has access to BadlyNamedClass.this.inventory;
};
this.inventory = new Inventory() {
... has access to BadlyNamedClass.this.owner;
};
}
...
}
Or even:
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User(this);
this.inventory = new Inventory(this);
}
public User getOwner() { return owner; }
public Inventory getInventory() { return inventory; }
...
}
This is one "solution", though the loss of one final is inconvenient.
class User {
Inventory inventory;
User () { }
// make sure this setter is only callable from where it should be,
// and is called only once at construction time
setInventory(inv) {
if (inventory != null) throw new IllegalStateException();
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
If you are only interested in JVM bytecode and don't care about coding in Java specifically, perhaps using Scala or Clojure could help. You'll need some kind of letrec machinery.
B: "Inventory created by the User is our last hope".
Y: "No, there is another."
If you abstract the references to a third party, you can control the relationship therein.
For example.
public class User
{
private final String identifier; // uniquely identifies this User instance.
public User(final String myIdentifier)
{
identifier = myIdentifier;
InventoryReferencer.registerBlammoUser(identifier); // Register the user with the Inventory referencer.
}
public Inventory getInventory()
{
return InventoryReferencer.getInventoryForUser(identifier);
}
}
public interface Inventory // Bam!
{
... nothing special.
}
// Assuming that the Inventory only makes sence in the context of a User (i.e. User must own Inventory).
public class InventoryReferencer
{
private static final Map<String, Inventory> referenceMap = new HashMap<String, Inventory>();
private InventoryReferencer()
{
throw ... some exception - helps limit instantiation.
}
public static void registerBlammoUser(final String identifier)
{
InventoryBlammo blammo = new InventoryBlammo();
referenceMap.add(indentifier, blammo);
}
public static void registerKapowUser(final String identifier)
{
InventoryBlammo kapow = new InventoryKapow();
referenceMap.add(indentifier, kapow);
}
public static Inentory getInfentoryForUser(final String identifier)
{
return referenceMap.get(identifier);
}
}
// Maybe package access constructors.
public class InventoryBlammo implements Inventory
{
// a Blammo style inventory.
}
public class InventoryKapow implements Inventory
{
// a Kapow style inventory.
}

Categories