• 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:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Recipe for disaster, or, Java noob writing a pattern recognition program

 
Ranch Hand
Posts: 441
Scala IntelliJ IDE Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm writing a program that recognizes patterns in data and tells me something about that pattern. So I create a Pattern class and give it a recognize method, and an array field to hold what I find out (as well as other fields to contain the data itself). I'm doing a lot of patterns so performance is an issue.

public class Pattern{

private int[] characteristics = new int[5];

public void recognize(){
.....
}
}



Time to write my method. Well, recognizing the pattern is not simple. I need to execute a whole bunch of different tests. How to structure the code?

My instinct is to create a bunch of subroutines that recognize() executes one after the other to look for each category of pattern. But you can't create sub-methods in Java.

So - create private methods within the body of the class and call those? But then all my variables go out of scope and I have to pass through all the relevant ones then pass an array of them back, then re-assign them to the original variables... seems very inelegant. Or, define all the variables at class level as fields, but again this seems inelegant since they're not object "properties" and should be disposed of when the method completes.

Or - write a monolithic method full of if{} blocks that check whether the pattern type has been found yet before executing the next block of code... again seems inelegant. My first attempt has done something like this, but I used labelled code blocks using { } and the break command, which I understand is frowned upon.

Or - make some nested classes called PatternRecognizer etc which contain all the relevant routines as methods and variables as fields? Then dispose of the PatternRecognizer object from the recognize() method when I'm finished? Not sure about this since I've never created a nested class before.

Any thoughts appreciated!
 
Marshal
Posts: 79178
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What is wrong with private methods? It is very easy to pass the variables to them as arguments.
Why are you trying to reinvent the wheel? There is already a Pattern class. You are going to have to find out about the grammar for regular expressions and how to parse a regular grammar.

Why don't you use the existing regular expressions API?

And welcome to JavaRanch
 
Luigi Plinge
Ranch Hand
Posts: 441
Scala IntelliJ IDE Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the welcome!

It's not a pattern of characters I'm analysing. If there's already a Pattern class it's nothing to do with my data... I just used the word Pattern as an example. The class I'm writing the method for is a collection of custom objects... details of what exactly it is isn't really important.

I have to create a whole raft of local data and variables in the analysis. I'm thinking that sending 20 different variables and a bunch of big arrays in the argument to a private method and then sending the whole lot back probably isn't the best way of doing things.

 
Luigi Plinge
Ranch Hand
Posts: 441
Scala IntelliJ IDE Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Say for argument's sake the object is a picture, and we want to analyse what it's a picture of.

We want to do this by scanning the picture and dividing it up into lines and regions, then doing tests for different shapes, colours, textures etc, and any test is capable of determining to sufficient certainty what it is. How would you go about it? (This is completely not the type of data I'm actually looking at but it might be the same principle.)

I don't think I'd really want to define private methods for every type of analysis I could do within the picture's class?
 
Campbell Ritchie
Marshal
Posts: 79178
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't know, I am afraid. But that is beyond the scope of "beginning" so I shall move this thread.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are all your recognition methods going to be processing the same (or at least similar) arguments? If so I'd define a class that encapsulates all those arguments. Then a single instance of that class is all you need to be passing to your various methods.

Once you've done that then having a load of private methods might not be so painful. If it is, or if you want your design to be a bit more flexible, you could use something roughly like the Strategy Pattern. You can find much better explanations than I can give by searching, but roughly speaking you'd:

- Define an interface that defines the method and signature that you want to call.
- Define a concrete implementation of the interface for each different test. These could be inner classes if you want to keep them in the same class, but they don't need to be.
- Set up a collection containing an instance of each of these concrete classes.
- Then your recognize method can iterate through them (stopping once a match is found, if that's what you want).

Something like this:

Sound any good?
 
Luigi Plinge
Ranch Hand
Posts: 441
Scala IntelliJ IDE Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Matthew - that sounds really good. Yes the input arguments into the methods can be the same.

When you mention the Strategy Pattern, are you talking about the book Design Patterns? I've heard of it although I don't have a copy. As you say, I can probably dig something up with a search. I came across a mention of something similar in Effective Java (another book I should probably read) when reading up on Comparators, where you create a single "public static final" instance of each.

The idea of encapsulating all the data in an "artificial" PatternArgs class seemed a bit weird to me to start with, but on further thought it seems like a pretty good approach. I could pass the Pattern object itself into the PatternArgs constructor and do the preliminary processing there.

I'll definitely look into this approach further. I'm still a Java noob but it should be a good learning process. I've barely read any "real" Java code (as opposed to snippets in books) so I don't know to what lengths people generally go to to split their code up into manageable chunks, or how long is "too long" for a single method.

Thanks for the advice!
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, that's the one. I haven't read it myself either, but there are quite a few books - and plenty of resources on the internet - that discuss that and other patterns.

Good luck with the project!
 
Catch Ernie! Catch the egg! And catch this tiny ad too:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic