Hi there. I've been working on a side project outside of class (I'm a Software Engineering student at Uni) which is really just a simple Banking system to help my understanding of Java. Basically the program reads existing accounts from a .txt file which are then placed into an ArrayList (they are split into Account objects).
The user can then choose to create a new account which added to the ArrayList or edit an existing one. I have three classes - the main class, Account class and UserInterface class. The main class holds all the methods such as SaveAccount (writes the accounts into file) etc. the Account class defines the account and then the UserInterface produces a UI to the user and interacts with them. The problem is I have the ArrayList in the main class and the only way to access it in UserInface is through making it public. My lecturer said this is bad since then the UserInterface class can edit it which I don't want. The thing is though I can't make the Account methods private as I want to edit them until they are put into the ArrayList so I'm not sure how to do it.
My only theory is copying the object to a duplicate class which has private settings before throwing it into the ArrayList. Would this work/be the best solution? Sorry if my question is long winded, I'll try to make it more concise if necessary.
7 replies to this topic
#1
Posted 30 October 2010 - 03:49 PM
|
|
|
#2
Posted 30 October 2010 - 08:19 PM
Hi LDM91
In your banking application in object oriented design perspective it's not a good idea to define lots of methods such as SaveAccount in the Main class. You could have define a class called Customer and put methods such as Withdraw and CreditAccount inside that class. As your teacher mentioned instance variables shouldn't be public. It's not a good design practice. Other clients can misuse it. Have you heard about getters and setters.? You can make instance variables private and use getters and setters to access and validate those instance variables.
Hope this will help you.
Cheers
In your banking application in object oriented design perspective it's not a good idea to define lots of methods such as SaveAccount in the Main class. You could have define a class called Customer and put methods such as Withdraw and CreditAccount inside that class. As your teacher mentioned instance variables shouldn't be public. It's not a good design practice. Other clients can misuse it. Have you heard about getters and setters.? You can make instance variables private and use getters and setters to access and validate those instance variables.
Hope this will help you.
Cheers
#3
Posted 31 October 2010 - 01:37 AM
You can make a getter in the Account class:
The unmodifiableList function returns a List, so you can do list.get(0) on it. You can also do list.remove(0);
It won't give errors on compiling, but if that code is executed it will throw an error because you can't edit an unmodifiablelist.
public List getAccounts(){
return Collections.unmodifiableList(arrayListName);
}
The unmodifiableList function returns a List, so you can do list.get(0) on it. You can also do list.remove(0);
It won't give errors on compiling, but if that code is executed it will throw an error because you can't edit an unmodifiablelist.
#4
Posted 31 October 2010 - 07:50 AM
Thank you both for the replies.
RE: reply 1:
I think I got a bit confused as I have the getter and setters in their respective classes, so it is slightly duplicated in a way I guess. The only reason I had lots of methods in the main was because I am scanning the input from the user and not just doing Account.SetID(1) for example.
RE: reply 2:
I understand what you're suggesting but I'm sure it is right to use it? As the ArrayList is an ArrayList of Account objects I'm not sure how setting that method is suitable here. Sorry if I have misunderstood.
RE: reply 1:
I think I got a bit confused as I have the getter and setters in their respective classes, so it is slightly duplicated in a way I guess. The only reason I had lots of methods in the main was because I am scanning the input from the user and not just doing Account.SetID(1) for example.
RE: reply 2:
I understand what you're suggesting but I'm sure it is right to use it? As the ArrayList is an ArrayList of Account objects I'm not sure how setting that method is suitable here. Sorry if I have misunderstood.
#5
Posted 31 October 2010 - 09:01 AM
Because ArrayList extends List, there is no problem in converting an ArrayList into a List;
If you really want your ArrayList back you can cast it
List<String> myList = new ArrayList<String>();Works without errors and myList will behave just like an ArrayList.
If you really want your ArrayList back you can cast it
ArrayList<String> myList = (ArrayList<String>) Collections.unmodifiableList(otherList);But that shouldn't be really necessary.
#6
Posted 31 October 2010 - 09:20 AM
You could make a subclass of ArrayList and have it implement an interface of your creation, that only defines the getting methods of the class, thus excluding the other methods from the returned object. Consider the following:
public interface NoModifyArrayList<E> extends Iterable<E>
{
boolean contains(Object o);
E get(int x);
int indexOf(Object o);
boolean isEmpty();
int lastIndexOf(Object o);
int size();
}
import java.util.ArrayList;
import java.util.Iterator;
public class SubArrayList<E> extends ArrayList<E> implements NoModifyArrayList<E>
{
// Everything is pretty much done except that NoModifyArrayList extends
// Iterable, which defines the iterator method. This method IS defined in
// ArrayList, so I could leave it as be, but this iterator can modify the
// list using remove(), so I have to have a new Iterator which works just
// like the ArrayList iterator except it throws
// UnsupportedOperationException upon use of remove().
private class NoModIterator implements Iterator<E>
{
public NoModIterator(Iterator<E> it) { this.it = it; }
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { throw new UnsupportedOperationException(); }
private Iterator<E> it;
}
public Iterator<E> iterator() { return new NoModIterator(super.iterator()); }
}
What I provided was only an example, you should make SubArrayList a private class of your Accounts class to contain all the loaded Account information, where you can write to SubArrayList. Then, you have your method return a NoModifyArrayList and just return your SubArrayList class, the compiler will enforce that the returned interface object could not have access to any modifying methods.
Wow I changed my sig!
#7
Posted 31 October 2010 - 09:53 AM
Thank you for the help. I will try what you have suggested later today and report back if I have any problems!
#8
Posted 01 November 2010 - 12:33 AM
ZekeDragon said:
You could make a subclass of ArrayList and have it implement an interface of your creation, that only defines the getting methods of the class, thus excluding the other methods from the returned object. Consider the following:
public interface NoModifyArrayList<E> extends Iterable<E>
{
boolean contains(Object o);
E get(int x);
int indexOf(Object o);
boolean isEmpty();
int lastIndexOf(Object o);
int size();
}
import java.util.ArrayList;
import java.util.Iterator;
public class SubArrayList<E> extends ArrayList<E> implements NoModifyArrayList<E>
{
// Everything is pretty much done except that NoModifyArrayList extends
// Iterable, which defines the iterator method. This method IS defined in
// ArrayList, so I could leave it as be, but this iterator can modify the
// list using remove(), so I have to have a new Iterator which works just
// like the ArrayList iterator except it throws
// UnsupportedOperationException upon use of remove().
private class NoModIterator implements Iterator<E>
{
public NoModIterator(Iterator<E> it) { this.it = it; }
public boolean hasNext() { return it.hasNext(); }
public E next() { return it.next(); }
public void remove() { throw new UnsupportedOperationException(); }
private Iterator<E> it;
}
public Iterator<E> iterator() { return new NoModIterator(super.iterator()); }
}
What I provided was only an example, you should make SubArrayList a private class of your Accounts class to contain all the loaded Account information, where you can write to SubArrayList. Then, you have your method return a NoModifyArrayList and just return your SubArrayList class, the compiler will enforce that the returned interface object could not have access to any modifying methods.That's exactly what Collections.unmodifiableList does.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account

Back to top









