aspose file tools*
The moose likes Java in General and the fly likes Trying to create OO based bank app Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Trying to create OO based bank app" Watch "Trying to create OO based bank app" New topic
Author

Trying to create OO based bank app

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Don't have time to read all that code, but initial amount to open an account does not belong in a keyboard input class.
Find out what SOLID means in OO programming. A lot of people no longer believe the O bit, but they do believe S. That means the account class takes case of its minimum, not the input class. There is however nothing wrong with an input method which insists on the amount being in a particular range.
You should design input from a Scanner not to use Exceptions, nor Integer.parseInt. Please search my posts for Scanner, utility class, etc. You should find enough there to enable you to create such a utility class. Beware: there is an error somewhere. And I haven't told you where.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Thanks Campbell, i read about SOLID and learnt new things but having same doubt on 'L' part. I will again read tonight and trying to get things clear.

You should design input from a Scanner not to use Exceptions, nor Integer.parseInt. Please search my posts for Scanner, utility class,


Checked your previous posts and accordingly corrected.. Thanks Campbell for pointing...

there is an error somewhere. And I haven't told you where.


I have double checked and found few of things which i have corrected now:

1) use of AtominBoolean instead i am using static flag
2) I used map as instance variable but instead i make it static
3) data storing, instead of defining here i have defined another utility class names StoreData which have a static method. I will call this method whenever i able to successfully create account and customer object and passed that data to it.
4) In another utility class which is taking input , i defined private constructor so that instance can not be created.
5) Also in that class i have changed method which taking amount as a input. removed minimum criteria and also improve so that it can receive amount > 0.


Are these one you talking about or i missed something?




Updated Bank class:


/**
*
*/



MyUtility Class



Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Tushar Goel wrote: . . .
there is an error somewhere. And I haven't told you where.

. . .Are these one you talking about . . .

No. Most of those things you described do look suspicious, and I suspect some of your changes have made them worse, but I meant an error somewhere in what I wrote. It shouldn't be too difficult to find if you read the whole thread.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
I suspect some of your changes have made them worse


I thought they were good. Please tell me what went wrong..


I meant an error somewhere in what I wrote


I think there is possibility of this reference escape before account constructor creates.. Is it correct ? I am also trying to think any other error..
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
I mentioned the error after I said to search. If you search as I said, then you are likely to find the error. At least the error I know about

The bit about letting a this reference escape is not an error.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
I searched again and read yours and other posts and also i read category UserInput , i think now you are referring to the case in which user entered input in wrong format. All others methods
except nextLine() method in Scanner class throws InputMismatchException if user entered input in wrong format.

Is this one you referring to? I tried hard to think about it and thought this only.

Also Thanks you, i come across very good posts and article related to Scanner/Utility class while searching for it. Thanks again..

This is the modified utility class:

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Tushar Goel wrote: . . . category UserInput , i think now you are referring to the case in which user entered input in wrong format. . . .
No, that wasn't the error I meant. If you search my posts for "Prasanna Raman daft mistake" you might get closer. Hint: restrict your search to posts after 16th January this year. And before 18th January. And read the whole thread.

I have a different opinion of Scanner from Winston's. You need to get to know how Scanner works and you need to let it do its work. You do not need to handle IOExceptions because Scanner does that for you. You do not need to deal with patterns and regexes because Scanner does that all for you. The only Exception you need to worry about is InputMismatchException, and Rob Spoor told me a long time ago that is completely avoidable. You use Scanner's methods and Scanner's methods only and you get a method which takes an int from the command line/terminal and repeats the prompt until a valid int is entered. Look through the methods of Scanner and see if you can work out how to do it. Probably better to return an int than an Integer.
You can overload that method to accept an int in a particular range. You can overload that message to display a custom error message. You put all those methods in a utility class. You work out whether that class will be thread‑safe or not without synchronisation.

Then you read what it says in the books about nextLine, and there is a good chance it will be wrong. The post I hope you have found now, with or without daft mistakes, and this post (minus the rant) will tell you what nextLine actually does. You should by now know how to write a static method which returns the next “full” line, i.e. the next line returned from the nextLine method for which trim().isEmpty() returns false. You can use that to get name entry. Because you are using that utility class as a universal resource, it should be in its own package. It should not have things like "invalid name" in. In fact you will get no error messages from this sort of code:-…for all the following inputsThe Scanner will simply ignore the excess whitespace and your method will silently skip the empty lines.
Since you are using that class as a universal resource you want to create methods to get doubles, BibDecimal, BigIntegers, etc from the keyboard similarly. Now you have a universal resource, you can use it for the banking app.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8418
    
  23

Campbell Ritchie wrote:I have a different opinion of Scanner from Winston's.

Very true.

You need to get to know how Scanner works and you need to let it do its work.

And that's basically it.

You do not need to handle IOExceptions because Scanner does that for you.

Agreed.

You do not need to deal with patterns and regexes because Scanner does that all for you.

And so does Integer, or Double, or whatever type you want to get from a String - including custom ones. So why would you want to use one approach just for the types that Scanner provides, and a different one for all the others?

I doubt we'll ever agree on this one.

Probably better to return an int than an Integer.

Not necessarily; and specifically not from integerOrNull(). After that, it very much depends whether you actually need an int or not. After all, there's no point in unboxing unnecessarily.

@Tashar: The methodology I describe in UserInput is by no means the only way to do it; I just find it easier. I mainly wrote the article to get you thinking about the business of input - ie, the validation loops.

If you decide you prefer Campbell's idea of using Scanner's own methods and learning the class properly, I'd be the last person to suggest you don't.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Paweł Baczyński
Bartender

Joined: Apr 18, 2013
Posts: 1048
    
  17

I think using static flags is not a good idea.
What if you have two instances of Bank class?


Formely Pawel Pawlowicz
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Winston Gutkowski wrote: . . . Very true.
Because there are always several ways to do things in computing and there are several correct ways to do it.
. . . So why would you want to use one approach just for the types that Scanner provides, and a different one for all the others? . . .
Because that approach will deal with 95% of all your keyboard inputs and you can write custom classes for all the others. Scanner provides input for all the primitive types and the two BigXXX classes in the java.math package.
. . .
Not necessarily; . . .
I did say probably, not definitely
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
When I wrote: . . . Scanner provides input for all the primitive types . . .
… I knew it was't true. There is no nextChar method (or at least there wasn't last time I looked). You would have to use next().charAt(0) but that is a bit like System.in.read() which I warn people against using.


Would Winston and I agree on that?

Another thing about using the hasNextXXX methods of Scanner: they allow you to inspect the next token and you can then request new input and completely obviate the need for Exception handling. You can even obviate NumberFormatExceptions
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
@Campbell.. I crack it. Thanks to you and Rob...

I have made little bit other changes to remove that alternate line display issue. In getNumber() method i used while instead of do-while.

It should be good now..




@Winston there are several correct way to achieve a common task. So both of you shared 2 separate way to achieve a common task. It is just which one is clicked... Thanks for the article.. It clear some of my doubts.

@Pawel Actually i was confused between to make a app as single threaded or multi-threaded. So initially i set it as instance variable and later changed it to static. But i think i should revert back to instance case.. Thanks for suggestion...

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Well done

I would call the method getInt not getNumber. I suggest you only need to print the prompt once in the getLine method and you might consider printing an error message like "Incorrect format for number: please try again: " in line 20.
You realise that lines 20 and 21 can be swapped round without any difference in output?

I suggest you start with a single‑threaded app at present. Only add threading if you need it. See this recent thread.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Well done

Thanks Campbell. though it took little longer but it got me learn several things..

I would call the method getInt not getNumber. I suggest you only need to print the prompt once in the getLine method

Corrected

You realise that lines 20 and 21 can be swapped round without any difference in output?

Yeah, no as such difference observed

I suggest you start with a single‑threaded app at present

ok.

After that i have modified by bank class.. Please check if it is ok..


Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Utility class:

/**
*
*/

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
The user name and date of birth methods don't belong in a utility class. The idea of the utility class is that you can use it for input for everything you write, not simply the banking app. You might do well have a generalised date method there which returns a LocalDate object, however.
Unless you own the website www.utility.org you should use a different package name. Package names are described in the Java Tutorials.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8418
    
  23

Tushar Goel wrote:@Winston there are several correct way to achieve a common task. So both of you shared 2 separate way to achieve a common task. It is just which one is clicked... Thanks for the article.. It clear some of my doubts.

Glad it helped; and, as Campbell said: WELL DONE.

As (I hope) you're starting to discover, there is no one "right" way to do things, which is why it's so important to understand WHAT you're doing (ie, the process involved), not HOW you intend to do it (the code).

Code is cheap, and can almost always be changed; what you're doing can't. Classes and objects and interfaces are mostly about 'what'; and the reason we have all these SOLID rules is so that if you don't like how you've done something, you can rip it out and start again.

For more information, you might try the WhatNotHow (←click) page.

Winston
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
which is why it's so important to understand WHAT you're doing (ie, the process involved), not HOW you intend to do it (the code).


This what i am learning from you guys and cannot be done without you guys help.. Thanks again to you, Campbell and other folks which helping us time to time...

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
You're welcome
I see you are putting the bank together bit by bit. I think that is the correct way to do it. I suggest your Maps should be parametrised classes. Not Map but Map<Customer, Account> or maybe Map<List<Customer>, List<Account>>
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
But remember what I said earlier about mutable types in Maps.

At least I think I said something earlier.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
But remember what I said earlier about mutable types in Maps.


Yes you told me about bi directional map and i am going to use Account and Customer as a attribute in this..

date method there which returns a LocalDate object

I am using 1.7 and do not have rights to install 8 as i am using my current employer laptop but will search for alternative..

the user name and date of birth methods don't belong in a utility class

Corrected

Unless you own the website www.utility.org you should use a different package name

corrected

If everything is fine till date (except dateOfBirth method which i correct soon) should i start working on customer class or anything i still missed in Bank class?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Tushar Goel wrote: . . .
Yes you told me about bi directional map and i am going to use Account and Customer as a attribute in this..
Remember what happens if keys in a Map change their hash codes.
. . .
I am using 1.7 and do not have rights to install 8 as i am using my current employer laptop but will search for alternative..
Look for Joda Time. It is supposed to be good, but I haven't used it myself.
. . . should i start working on customer class or anything i still missed in Bank class?
You appear to be working on the create account method. That needs a Customer and an Account, so you will have to implement thsoe two classes before you can finish that method.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Remember what happens if keys in a Map change their hash codes.


Yes, i need to make sure that account and customer object have unique hash code and that can be achieved using unique account and customer id...

You appear to be working on the create account method

I started earlier but i stopped and thought to go in slow space and concentrate on one class first.. I have not done anything till now.

Ok, so should i start with customer class first and meantime i will read about Joda time.?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
You decide whcih class you are going to create first.
Create the classes as standalone apps, possibly with their own main methods each, as it tells you not to do here. Put code in those main methods to test all the methods of the class. Then you will know the class works


Then you can get rid of the unnecessary main methods, maybe by changing their access to private.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
I have added date method in utility class. I have one doubt here, if i passed directly string as below it always showing month as Jan but Year and day is same as i passed. I dont understand why?

String date = .... ;



To overcome this i need to split the string by delimiter and create a local object and passed each of the part into this. Then it working fine...




Also i tried to test my utility class. This is my first attempt to use JUnit...


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
If you are using Scanner why use Integer.parseInt? That risks throwing a NumberFormatException and the idea of those loops with Scanners is to get rid of all Exceptions.
Go through the Scanner documentation and see whether there is any way to get a date out of it. (I couldn't find anything.)

You can create a Scanner to scan a String, and tokenise that String. Then you can inspect the tokens and you can obviate the Exception like this:-That is crude code which I knocked together in two minutes, so you can probably improve it. You know that Calendar.JANUARY ≠ 1, I presume?

Totaly different approach.
Google for Toedter and Calendar applet. Toedter has a calendar applet which you call and you get a popup with a date picker on. You highlight July 2014 and 5 and you get a Date object returned.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
You will have difficult with asserting equals between
"06-Jan-86"
and a
date in dd-mm-yyyy format
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
That risks throwing a NumberFormatException and the idea of those loops with Scanners is to get rid of all Exceptions.


Actually, i am thinking, it may not throw any number format exception.. I already using a loop which will capture all the wrong input and only correct input goes to parse method....
May be i am wrong or have not done enough testing?




Testing:
Enter date of birth (dd-mm-yyyy): ee-ee-eeee
Enter date of birth (dd-mm-yyyy): qq-ee-qqqq
Enter date of birth (dd-mm-yyyy): 11-ee-111
Enter date of birth (dd-mm-yyyy): 11-11-2002

output: 11-Nov-2002

Though i will try to do it your way as well...

You will have difficult with asserting equals between

Thanks, i will modify it to dd-mm-yyyy but when i tested there was not problem. After receiving input in mm-dd-yyyy formnat, i am changing it to dd-mm-yy and then comparing it.
But i think that's not a good way. So will change it.. Thanks...

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
The more ways you try, the more chance there is of finding the best way
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Agreed.. Silly me..

I am away for 2 days and get back on monday. I will paste updated code then...
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
I mixed both of us idea and come up this method. do-while loop accepts the input in correct format and then with scanner methods
i get day , month and year details. This will help to avoid any input mismatch exception and i think better then my previous
version:

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Why are you only using hyphen as a delimiter? You can set up a regex which will accept space, punctuation etc or a combination as a delimiter. Then you can pass 7/7/14, 7.7.14, 7:7:14, 07-07-14, 07 07 14 etc and they can all be recognised. This part of the Java® Tutorials will probably help you.
If you are feeling really ambitious, you can accept words and get them with a MapHave you confirmed that January == 1 for LocalDate?
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Why are you only using hyphen as a delimiter?

Sorry, i was not able to think it make more generic

This part of the Java® Tutorials will probably help you.

Thanks.. It helped me to make it more generic. They are like Perl. I did work on some perl 2 years back but forget about it now.



If you are feeling really ambitious, you can accept words and get them with a Map

Thanks for the way but may implement it later

Have you confirmed that January == 1 for LocalDate?

No, they are not.. We need to use Month class which have static variable as JANUARY. Just for your information, i am using joda time
They are methods available from which we can get specific date,month in integer or string format. There are so much available to read
but i read some part of it only.

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Getting along nicely

I would have used something like [\\p] or [\\p\\s] for the separator and \\d{1,2} for the numbers. But \\W looks good. Go back to that tutorial and check. I believe the Java® regular expressions framework is based on Perl, but again not certain.

I suspect that the Java8 time API is based on Joda time; others may know more than me.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
Getting along nicely


Thank you..

I would have used something like [\\p] or [\\p\\s] for the separator and \\d{1,2} for the numbers. But \\W looks good. Go back to that tutorial and check.

I have re-read the tutorial and updated my REGEX part now it is accepting only day upto 1-31 , month 1-12. Also i tried to put a logic to check if user entered correct day
in that month or not. i.e. user can not enter 30 or 31 day for Feb month etc..


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
I presume that is part of the keyboard inputs class? Getting better.
I think convention has it that you write private static final rather than private final static but that is only a minor style point. The field might better be called DATE_REGEX; then it is obvious to all reading it what it means.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
I presume that is part of the keyboard inputs class?


Yes, it is.

private static final rather than private final static


Corrected

The field might better be called DATE_REGEX;

Corrected


What should i do next now?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
Confirm that every method in the keyboard input class works, for normal and abnormal input. Then you can put it away and use it for all sorts of other applications.
Tushar Goel
Ranch Hand

Joined: Dec 29, 2013
Posts: 261
    
    1
It seems working fine for me for the inputs i passed.. Though i have 1 doubt here. While testing i found out that nextInt() in getDate method remove leading 0s from the input.
So say if i entered 01 01 1990 then it will remove and give us like 1 1 1990. It seems to be issue with me. Rest is looking fine.


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40041
    
  28
You would never expect to have leading 0s in numbers.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Trying to create OO based bank app