• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Trying to create OO based bank app

 
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Bartender
Posts: 2237
63
IntelliJ IDE Firefox Browser Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think using static flags is not a good idea.
What if you have two instances of Bank class?
 
Campbell Ritchie
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Utility class:

/**
*
*/

 
Campbell Ritchie
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But remember what I said earlier about mutable types in Maps.

At least I think I said something earlier.
 
Tushar Goel
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You will have difficult with asserting equals between

"06-Jan-86"

and a

date in dd-mm-yyyy format

 
Tushar Goel
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The more ways you try, the more chance there is of finding the best way
 
Tushar Goel
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Agreed.. Silly me..

I am away for 2 days and get back on monday. I will paste updated code then...
 
Tushar Goel
Ranch Hand
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 954
4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 80634
471
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You would never expect to have leading 0s in numbers.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic