• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
  • Bear Bibeault
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • salvin francis
  • Stephan van Hulst
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Jj Roberts

Type for phone number?

 
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am working on an addres book in which I am trying to make phone number a type.

If landline and mobile have slightly different formats but same number of digits, would it be better to have an abstract class and then have landline and mobile inherit from it?

I was trying to do it using enums, but I am not sure how the different formats and all the validation can be handled here.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually on second thoughts, I've made it one class with 2 fields which make it generic:



Is this reasonable? In my hashcode and equals, I am using only the prefix and number and not the type.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is there a way to persist the data between runs without using a database or saving it in a text file? What's the simplest way to do this?
 
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:. . . In my hashcode and equals, I am using only the prefix and number and not the type.

That would work all right if the set of landline numbers and the set of mobile numbers are completely disjoint from each other (they usually are but only if you confine your attentions to one country). Beware of this sort of number:-I think you should program your methods so all the numbers in those blocks count as equal.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah ok! So should I actually include the type in the comparison to make sure I can account for various countries?

Also, what sort of validations should I provide for an address book of this sort?
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:. . . should I actually include the type in the comparison to make sure I can account for various countries?

Maybe yes maybe no. I might go with different classes myself.

Also, what sort of validations should I provide . . . ?

Don't know. Maybe validate that phone numbers can be reduced to repeated digits. Maybe require a certain first digit (often 0) or ban a certain first digit (I think, in the USA, 1).
 
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'd imagine that phone numbers within a geographic region like a country would be unique, regardless of the format. There's another implied prefix there though: the country code. When I'm dialing from within the US, I don't have to prefix every number I dial with 1, the US country code. If I wanted to call a US number from outside the US, I'd probably have to dial an International call prefix first (like 0 or 01) the country code, then the area code, and then finally, the actual phone number. That is, if my phone number in the US was (123) 555-1234 and my friend in the Philippines wanted to call me, he'd have to dial something like 01 1 123 555 1234.

I don't know if you want your phone book to handle all that though.

As for the formatting, I'd be inclined to use a Formatter type class and maybe add on a Factory that can give back a proper formatter based on country code and phone type. Creating an entire Phone class hierarchy just for formatting seems a bit heavy-handed to me.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Junilu,

Can you please expand on what you mean by Formatter type and the formatting factory? I am not following.
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, from an API standpoint, I'd want the task of formatting a phone number to be relatively abstract for the client. I don't want to know nitty-gritty details, just enough to get what I need.

I'd play around with a design that allowed you to write something like this:

This way, you can limit changes to your formatting logic around one class, the PhoneFormat class. For the client, all I know is that I can get an array of Locales that support a specific phone number format and that I can also specify the type of phone number. For US phones, for example, there's no difference between a land line and a mobile phone number: both are formatted as (123) 456-7890. In a different locale, there may be a difference. All that logic is encapsulated PhoneFormat though.

Or I might play around with a design where you have to write something like this instead:

There are many ways you can design the API but the general idea is that the logic is encapsulated in a Formatter class and you have a Factory method that can give you back an appropriate instance of Formatter based on parameters you provide to it.
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I often look to the standard library for ideas on how to design things. The idea above is patterned after (stolen from) the standard DateFormat class: https://docs.oracle.com/javase/8/docs/api/java/text/DateFormat.html

My reasoning is that if I follow a pattern that already exists in the standard library, then the design is likely to be more intuitive to people who are already familiar with the standard library design and usage. The caveat is that you have to recognize that there are some classes in the standard library that are not well designed and avoid making the same mistakes they did.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, that country parameter is just a String in this case? Would you have separate classes for each country? Or have switch case type logic?
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How do I persist the data between application runs? If I used a Map to load the initial data, the new data added would get lost?
 
Marshal
Posts: 26132
77
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:How do I persist the data between application runs? If I used a Map to load the initial data, the new data added would get lost?



Well, yes, but that's true of any type you would choose. If you want to persist the data there are several ways to do that, but it's a separate topic from this one.
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:So, that country parameter is just a String in this case? Would you have separate classes for each country? Or have switch case type logic?


It's just an idea. If you want to implement it that way, I suggest you look at the DateFormat class source code (Google for source code of DateFormat java) for more details. That's what I would do if I were trying to implement it like that. I would also look into how Locale works. I would also ask myself if I really need to take it that far. Do you really need to support formats for many different places? Maybe you can start simpler for now? I don't know. These are all things you need to decide for yourself.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I'll stick to just one country now. Even then, should I have a formatter class?

Would my phone number be an abstract class and then my USPhoneNumber be an implementation of it?
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:Would my phone number be an abstract class and then my USPhoneNumber be an implementation of it?


That's not really what I was suggesting, was it? That's almost diametrically opposite of the suggestion to use a Formatter and a factory method. Like I said earlier, I think having a hierarchy for a PhoneNumber just because you want to be able to format it differently doesn't seem right to me. The Date class doesn't have subclasses for different formats. Why should a PhoneNumber class have subclasses for different formats?
 
Rancher
Posts: 924
22
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Serialize the object, your class must implement Serializable, but then you are saving in a text file.  To persist data from run to run, you must materialize it somewhere... so unless you have an instance that cannot go down, no such thing, you have to save it out to some physical device at some point.  I've always chosen databases, as they give a much better interface for data access and manipulation outside of the project piece developed in Java.

Prasanna Raman wrote:Is there a way to persist the data between runs without using a database or saving it in a text file? What's the simplest way to do this?

 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Junilu,

Assuming I'm only dealing with 1 country here,

If I just take in any 10 digit phone number, could I format it based on whether it is landline or mobile based on type?

So the formatter would format based on the type of number.

Also, is it standard for an address book to have restrictions around length of the number entered?
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:. . . Assuming I'm only dealing with 1 country here,

Then you probably only need one PhoneNumber class.

If I just take in any 10 digit phone number, could I format it based on whether it is landline or mobile based on type?

Why do you need a type? Where I am it is very easy to tell landline numbers from premium numbers and mobile numbers. Mobiles begin 07, landlines begin 01 02 03 and premium numbers begin 09 (or some 08). But they all have eleven digits. The number of digits obviously varies from country to country. You can express that with a regex to validate the phone number, probably best done in the constructor. Don't try storing the numbers as ints or longs, because phone numbers aren't numbers.

So the formatter would format based on the type of number.

Yes.

Also, is it standard for an address book to have restrictions around length of the number entered?

Where do you think it the best place to validate the format of a phone number?
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The best place to validate would be in the constructor?

So, I would initialise a phone number like,

new PhoneNumber("prefix", "number"); // landline or mobile

Constructor would check to see if digits is a fixed length.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also, I am a bit confused by what the formatter is supposed to do.

If the user enters a 1234567890 number, it would then store it or print it as

(123) 456 7890 // an example US number

Is this the use of the formatter if I understand correctly?
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:Also, I am a bit confused by what the formatter is supposed to do. . . . .

I think that is for you to decide.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, but what I've posted here for the formatter to do - is that a reasonable thing for it to do?
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes.

Do you have overlaps between mobile and landline numbers anywhere? We don't.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No overlaps, but the formatter may do things like formatting landline numbers and mobile numbers differently.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Why do you need a type? Where I am it is very easy to tell landline numbers from premium numbers and mobile numbers. Mobiles begin 07, landlines begin 01 02 03 and premium numbers begin 09 (or some 08).



If a user wants to see on the addressbook or save it as a 'mobile' or a 'landline' number, how can I support this operation without creating an explicit PhoneType class or enum?
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:
Or I might play around with a design where you have to write something like this instead:

There are many ways you can design the API but the general idea is that the logic is encapsulated in a Formatter class and you have a Factory method that can give you back an appropriate instance of Formatter based on parameters you provide to it.



Hello Junilu,

I have the following to start with. Can you please tell me if this is reasonable? I am stuck on what to do after this though.



I'll probably need to create an inheritance hierarchy based on locale, like the below? But I know you'd said this wasn't the approach you were suggesting.



In this case, I'll have to create classes for each country still and then also separate classes for each phoneType?
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I feel as if I am going around in circles with this one unfortunately I played around with putting the format as an abstract method inside the Locale enum for each locale to override, but that doesn't seem to be a good idea either! Please help!
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, you can declare abstract methods in an enum, but you need to override them first(!) There is an example about arithmetic in the Java® Language Specification (=JLS), which I suggest you emulate. You can add things like country code to each of your enum constants, too. I recommend you read the whole JLS chapter about enums.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Yes, you can declare abstract methods in an enum, but you need to override them first(!) There is an example about arithmetic in the Java® Language Specification (=JLS), which I suggest you emulate. You can add things like country code to each of your enum constants, too. I recommend you read the whole JLS chapter about enums.



Thank you, just looked at the arithmetic eval function in the link you provided. So, actually putting the format() method inside the enum is good design here? That's where I am getting confused!

I have a PhoneFormat class which returns a PhoneFormat object from a factory method but not sure yet how to implement that method.
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Prasanna Raman wrote:
Assuming I'm only dealing with 1 country here,

If I just take in any 10 digit phone number, could I format it based on whether it is landline or mobile based on type?

So the formatter would format based on the type of number.


If those were the requirements you're starting out with, I'd start with a simple design. Not sure why you're asking if you could format based on the phone type. If that's what you need to do, then that's what you should do.

Off the top of my head, there are a couple of things I'd probably do:
1. Have a reasonable default so that I could just get a default formatter with PhoneFormat.getInstance()
2. Still keep the design open to extension by having PhoneFormat.getInstance(PhoneType type)
3. Use a Map internally to map PhoneType to an appropriate pattern to use for formatting a phone number. The getInstance methods would return a PhoneFormat instance that uses an appropriate pattern.

I don't know how I'd feel about a PhoneType enum that encapsulated the format pattern. My gut sense is that it's not an appropriate assignment of responsibility but I could be convinced I was wrong if I had code to actually look at.
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Junilu. I am struggling with how to implement the factory class. How should I proceed from here?



I know I need to use the 2 parameters passed to getInstance in the factory class somehow, but not sure how I can create the instances.


 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've made some progress, not sure if this is ideal. Please review.







Is this reasonable? Now, where and how do I implement that Map you were talking about?
 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is this better?

 
Prasanna Raman
Ranch Hand
Posts: 539
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now for the getFormatter(Locale locale, PhoneType type) method, how do I implement this if I need to provide formatters based on both locale and type?

Even in the detault formatter, I will need to do conditional based on landline vs mobile! If a new locale gets added, then I need to get the correct formatter for the locale, and then somehow get the correct formatter for the type for the locale! I am probably confusing myself here, but it keeps getting complicated and I am not sure how to solve this.

Upon thinking about this further, is this where I could do something like this?



But even this doesn't solve the problem of how I write the logic to format based on locale and also type Unless I have a formatter for each subtype - as USMobileFormatter, USLandLineFormatter etc..
 
Campbell Ritchie
Marshal
Posts: 71084
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are several ways you can store a formatter object.
  • You can put it into a map as the “V”, but I shall leave it to you to work out what to use as the “K”.
  • You can have subclasses as I suggested here, with formatters being private static fields of each class.
  • If you are using Locales, you might be able to put formatting information into a resource bundle (not sure).
  • You can have it associated with the type enum. But I remain to be convinced that you need a type enum in the first place; do you have an intersection of the range of phone numbers anywhere so there is a landline and a mobile with the same number in the same country? Would you need an additional (?prefix) number to disambiguate them?
  • Ouch! How are you going to describe that in the documentation? Look at that awkward code with two dots in. Why doesn't the toString() method return the phone number correctly formatted? Also a plainToString() method which returns my phone number in the blank formatrather than correctly formatted like this?If you go back to an earlier suggestion that you have a prefix (area code, dialling code, etc.) and number stored as separate fields, can you separate a String into its constituent parts in the constructor?
    What about a factory method requiring a non‑null locale as a parameter, returning subclasses of PhoneNumber? Then make all your constructors private.

    I you are confining yourself to one country only, then a lot of this current post doesn't apply.
     
    Prasanna Raman
    Ranch Hand
    Posts: 539
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:There are several ways you can store a formatter object.

  • You can put it into a map as the “V”, but I shall leave it to you to work out what to use as the “K”.
  • You can have subclasses as I suggested here, with formatters being private static fields of each class.
  • If you are using Locales, you might be able to put formatting information into a resource bundle (not sure).
  • You can have it associated with the type enum. But I remain to be convinced that you need a type enum in the first place; do you have an intersection of the range of phone numbers anywhere so there is a landline and a mobile with the same number in the same country? Would you need an additional (?prefix) number to disambiguate them?
  • Ouch! How are you going to describe that in the documentation? Look at that awkward code with two dots in. Why doesn't the toString() method return the phone number correctly formatted? Also a plainToString() method which returns my phone number in the blank formatrather than correctly formatted like this?If you go back to an earlier suggestion that you have a prefix (area code, dialling code, etc.) and number stored as separate fields, can you separate a String into its constituent parts in the constructor?
    What about a factory method requiring a non‑null locale as a parameter, returning subclasses of PhoneNumber? Then make all your constructors private.

    I you are confining yourself to one country only, then a lot of this current post doesn't apply.



    I have the enum not because there is overlap, but because I want the user to be able to select the phone number type when storing, and when viewing. If including the type as part of the phone number is not the ideal way to do this, then please tell me how else this can be done. I probably have bad design here.

    As for storing in map, I do have that map in the PhoneFormatProvider class, and also the inheritance hierarchy for the formatters (based on locale) as suggested by you earlier; but what I don't know is how I can also include the type within the formatter. Should I have USMobileFormatter, USLandlineFormatter etc.?

    Unfortunately, I don't understand what you're trying to say with the toString() methods Can you please elaborate?
     
    Prasanna Raman
    Ranch Hand
    Posts: 539
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:If you go back to an earlier suggestion that you have a prefix (area code, dialling code, etc.) and number stored as separate fields, can you separate a String into its constituent parts in the constructor?
    What about a factory method requiring a non‑null locale as a parameter, returning subclasses of PhoneNumber? Then make all your constructors private.



    Can you please elaborate on this? I do have a prefix and a phone number field for my PhoneNumber class, in addition to the PhoneNumberType field. I don't understand the parts about the constructor and the factory method
     
    Why should I lose weight? They make bigger overalls. And they sure don't make overalls for tiny ads:
    the value of filler advertising in 2020
    https://coderanch.com/t/730886/filler-advertising
    reply
      Bookmark Topic Watch Topic
    • New Topic