Some information (don't want to confuse you with a lot of shitty code):
I've done a pretty large console programm (my largest project so far) which helps me a lot with managing some accounts / assets and more. I'm constantly adding more features but at the same time I reshape the code to work on my shitty coding style.
The console program has a lot of commands the user can type and for every command different methods get called / objects get created / manipulated and so on.
My keywords which are saved in an ArrayList<String> and my commands have this type: [keyword] [...n more Strings]
DESIGN PROBLEM 1:
I have a method cmdProcessor(String[] arguments) which handles the input (command) of the user, and the [keyword] is always the first argument arguments[0]. That means I have a large number of if-statements of this type:
if(arguments[0].equalsIgnoreCase("keyword") callMethod(argmts); where in the String[] argmts the remaining arguments[1] ... [n] are.
Is this a good way to handle this or should I go with switch-case?
Or something else (what?)? Is it better to save the keywords in a HashMap<String, Method>?
DESIGN PROBLEM 2:
The methods (see above callMethod(argmts) ), which are triggered by the entered keyword look even more chaotic. Since the same method can have different numbers and forms of arguments saved in the String[] argmts the method is full of if(argmts.length == ...) to check length, and every of these if-blocks has a bunch of switch-case options which also have a lot of ifs and so on. The last else and the default-case in switch-case I always use for error-handling (throwing error codes and and explanation why the pattern doesn't match and so on).
Is this good or are there better ways?
I thought about using lots of submethods, which would also blow up
my program and cost a lot of time but maybe improve readability / overview. Is this okay, or what is the best
option in such cases (lots of ifs and switch-case)?
Since I want to build more and more around this program maybe I should start now to fix bad design before it's too late. :)
About Design-Problem 1:
My go-to would be to register a lot of Handlers, which you can base on a common interface and then implement the specific behavior individually. This is good, because the central method handling your input is slim, and you only need to register a lot of singletons once, on initialization. Disadvantage: if you forget one, it will not work. So maybe, you can register them automatically (reflection or something thelike).
Aside from that, a map is better than a List in this case, because (I assume) you don't need a sorting. You need a mapping from key to behavior, so a map seems better (though even a very large set of keywords would probably not be very inefficient, if you stick to a list).
About Design Problem 2:
If I was you, I'd use actual Regular-Expression patterns. Take a look at the java.util.regex.Pattern-class. You can isolate groups and validate the values you receive. Though it does not spare you the exception/error-handling, it does help a lot in segmentation and interpretation efforts.
Related
I just want to get some information before I go ask my teacher during his offices hours tomorrow.
We have have project to do thats something like an iclicker question answer collector. He told us to avoid using switch case statements. I was just wondering why and why don't people in the field like using them, what alternative is there to do? and I doubt he wants us to use if statements either.
I think we have to use polymorphism/interfaces but I just cant rap my head around that, switch cases seems so much straight forward.
Thank you.
Usually when an instructor asks "don't use feature X", it's because they want you to learn how to do something without using a feature that might be a shortcut. In your case, it sounds like your instructor wants you to wrap your head around polymorphism. If you don't, you won't learn that bit and will have much more trouble later in the class.
It depends upon the project. For example, in using a RESTful APi, you do have switch statements because there is a limit, known set. But, with your program there might be a lot of different options and that option can change, increase (or decrease), so while you started out with three cases, then something else is wanted, that's four, then five, and so on. You end up with 50 cases, and that's probably not good or easy to maintain.
With your OOP class, the instructor is probably going to show you that. Come back and show the whole problem and the final result, and maybe others can shed light.
There's an example that I've seen in my old Java book, and did a search and see it is still decent. Consider employees and salaries. You have three types of employees, then you have 50 types.
On a small scale, there appears to be not much difference. It requires enlarging the problem and considering consequences.
Ways to eliminate switch in code
That is a good example. Sure, there's only two cases in that example. But, again, what if it were 50? How easy will it be to maintain that? A lot of things in programming are about saving time and making things logical in the long run, as you will be coming back to your code or someone else's, and you have to maintain and support it.
I want to make a Java program to help people with basic discrete mathematics (that is to say, checking the truth values of statements). To do this, I need to be able to detect how many variables the user inputs, what operators there are, and what quantifiers there are, if any (∃ and ∀). Is there a good algorithm for being able to do all these things?
Just so you know, I don't just want a result; I want full control over their input, so I can show them the logical proof. (so doing something like passing it to JavaScript won't work).
Okay, so, your question is a bit vague, but I think I understand what you'd like to do: an educational aid that processes first-order logic formulas, showing the user step by step how to work with such formulas, right? I think the idea has merit, and it's perfectly doable, even as a one-man project, but it's not terribly easily, and you'll have to learn a lot of new things -- but they're all very interesting things, so even if nothing at all comes out of it, you'd certainly get yourself some valuable knowledge.
I'd suggest you to start small. I'd start by building a recursive descent parser to recognize zero-order logic formulas (a machine that would decide if a formula is valid, i.e. it'd accept "A ^ B" but it'd reject "^ A ^"). Next up you'd have to devise a way to store the formula, and then you'd be able to actually work on it. Then again, start small: a little machine that accepts valid zero-order logic formulas like TRUE AND NOT (TRUE AND FALSE), and successfully reduces it step by step to true is already something that people can learn from, and it's not too hard to write. If you're feeling adventurous, add variables and make equations: A AND TRUE = TRUE -- it's easy to work these out with reductions and truth tables.
Things get tricky with quantifiers that bind variables, that's where the Automated theorem proving may come into play; but then, it all depends on exactly what you'd like to do: implementing transformations into the various normal forms, and showing the process step by step to the student would be fairly easy, and rather useful.
At any rate, I think it's a decent personal project, and you could learn a lot from it. If you're in a university, you could even get some credit for it eventually.
The technique I have used is to parse the input string using a context free grammar. There are many frameworks to help you do this, I have personally used ANTLR in the past to parse an input string into a descrete logic tree. ANTLR allows you to define a CFG which you can map to Java types. This allows you to map to a data structure to store and evaluate the truth value of the expression. Of course, you would also be able to pull out the variables contained in the data structure.
I'm learning Java and find myself sending methods around while asking for help but my problem is I have many methods and the data is modified at each method. I often have to send large files when only one area is relevant(it makes my SO questions excessively long as well).
But for some of the stuff I do, I can't get the right data format to be outputted as string that I can input later. For example, if I add data to a list of Points(like this, (new Point(0, 0));) then when I output the results I get something like this(with sample data):
[java.awt.Point[x=970,y=10], java.awt.Point[x=65,y=10], java.awt.Point[x=729,y=10]
I get errors when I assign this to a variable and send it to my method I want to test/show. I basically have two goals:
If I want help on a single method(thats part of a much larger class), I want to be able to send the least amount of code to the person helping me(ideally just the method itself and the inputs..which I'm unable to capture exactly right now).
When I test my code, I would like a way to isolate a method so I don't have to run a large file when all I can about is improving one method.
I am pretty sure I'm not the first person to come across this problem, How can I approach this?
UPDATE: Here's an example,
double[] data = new double[] {.05, .02, -.03, .04, .01};
System.out.println(data); //output is: [D#13fcf0ce
If I make a new variable of this and send it to a method I get errors. I have 30 methods in a class. I want to have a friend help me with one. I'm to avoid sending 29 methods that are irrelevant to the person. So I need a way to capture the data, but printout doesn't seem to capture it in a way I can send to methods.
Java outputs variables in a way that is human-readable (although it depends on the object's toString method). The output of toString is (unsurprisingly) a String. Unless you have a parsing mechanism to turn a string back into the original object, it's a one-way operation.
There should be no need to turn it back into the original object, however. If you're trying to isolate a function and sample data, the easiest thing to do is encapsulate it in a test and some data--there are many different ways to do this and communicate it to someone else.
I'm still unclear on your usecase, however. If it's an SO question, all you should need to do is show the code in question, provide a minimal amount of data that shows the problem, and you're done. This could be done in a self-contained example where you simple create the data in code, as a unit test, or by showing the string output as you've already done.
If you're trying to communicate the issue to a tech support tier, then the best mechanism depends entirely on what they're equipped to handle--they'll tell you if you didn't do it right, believe me.
You can use Debuggers and step over your code. You can 'watch' variables so that you can get their actual value, rather than their toString representation. Debuggers are usually part and parcel with all the major IDE's such as Eclipse, Netbeans and IntelliJ.
As to your questions about isolation and testing, this is much more of a design problem. Ideally your methods should be self contained, reducing coupling. What you could do is to learn to break down your problem into smaller chunks and until it can't be broken down further. Once you do this, you start building methods which tackle each part of the problem seperately.
Once you have your method, you test it on its own (thus reducing the amount of things which can go wrong, as opposed to testing tons of code at once). If you are satisfied, you integrate the method with your code and test again. If something then goes wrong, you will know that your last module is the problem since it broke your system. You can get some more information about this here.
i need help modelling a use case diagram from a topic, it will be in java GUI
Design a Calculator that
1.Allow user to key in a legitimate arithmetic statement that involves number, operator +, - and bracket '(' and ')' ;
2.When user press “Calculate” button, display result;
3.Some legitimate statement would be ((3+2)-4+2) (equals 3) and (-2+3)-(3-1) (equals -1);
4.You should NOT use a pre-existing function that just take in the statement as a parameter and returns the result but you should write the logic of parsing every character in your code.
5.Store the last statement and answer so it is displayed when user press the “Last calculation” button.
i have designed two use case diagrams using UML on netbeans 6.5.1, one of the use case i am not sure whether is it containing too much use cases etc, while the other is what i think could be too vague for the topic.i hope to get some feedback on whether the use case diagram are appropriate, thanks.i included a what it would be like in GUI
First thing you must know about use case diagrams is that its supposed to describe functionality of a system for which actor. It should be on such a high level that anyone without knowledge of programming can understand it. As a programmer, use cases might look very vague to you but thats fine. Its not supposed to say anything about the system, just what it can do.
Some more specific comments:
As i mentioned use cases should describe high level functions. Press Calculate is not a function, Calculate is. Press Last Calculation should be Store Last Calculation, etc
Its not clear what Press Backspace does. Backspace is just a key, not a use case.
The ParserSys package tries to describe internals of a system. This does not belong in a use case diagram. Other diagrams should be used for this.
Use case Store Result (first pic) should not be in this diagram. But if thats something User can do, it should be associated with User.
Edit:
..i believe the main problem is i am having trouble identifying use case..
A good way of identifying use cases is as simple as asking yourself the question: "[Actor] should be able to [what]" (or something similar). [What] is then your use case. If it doesn't fit in this sentence, its probably not a use case.
In the second use case diagram, you have user having use cases based on the sequence of actions performed to implement the use cases in the first. These would be better represented as either an activity diagram or state machine - the user cares about getting the results of a calculation, and it is incidental that to get these results expressions need to be keyed in buttons need to be pressed. When creating use cases concentrate on the goals that the originator of the use case has, rather than how the system might help them achieve these goals .
On another point, the spec you give says nothing about simulating a keyboard using a Java GUI, or a backspace key as in your mock-up. Check with the stakeholders whether 'allow the user to key in' just means giving them somewhere to type, or providing an on-screen keypad.
I have a piece of xml that contains optional non-enumerated elements, so schema validation does not catch invalid values. However, this xml is transformed into a different format after validation and is then handed off to a system that tries to store the information in a database. At this point, some of the values that were optional in the previous format are now coded values in the database that will throw foreign key constraint exception if we try and store them. So, I need to build a process in a J2EE app that will check a set of xpaths values against a set of values that are allowable at those spots and if they are not valid either remove them/replace them/remove them and their parents depending on schema restrictions.
I have a couple options that will work, but neither of them seem like very elegant/intuitive solutions.
Option #1 would involve doing the work in an xslt 1.0. Before sending the xml through the xslt, querying up the acceptable values and sending the lists in as parameters. Then place tests at the appropriate locations in the xml that compares the incoming value against the acceptable ones and generates the xml accordingly.
This option doesn't seem very reusable, but it'd be very quick to implement.
Option #2 would involve Java code and an xml config file. The xml config file would layout the xpaths of the needed tests, the acceptable values, the default values (if applicable) and what to take out of the doc if the tests fail.
This option is much more reusable, but would probably double the time needed to build it.
So, which one of these would you pick? Or do you have another idea altogether? I'm open to all suggestions and would love to hear how you would handle this.
Sounds to me like option 2 is over-engineering. Do you have a clear idea about when you will want to reuse this functionality? If not, YAGNI, so go for the simpler and easier solution
Both options are acceptable. Depending on your skills and the complexity of your XML, I would say that it will require about the same amount of time.
Option 1 would be in my opinion more flexible, easier to maintain in the long run.
Option 2 could be tricky in some cases, how to define the config file itself for complex rules and how do you parse it without having to write complex code? One could say, I'll use a dom4j visitor and I'll be done with it. However, option 2 could become unnecessarily complicated imho if you deal with a complex XML structure.
I agree here. It felt like it was borderline over-engineering, but I was afraid that someone hearing that this was done would assume that it would be reusable and attempt to design something that used it in the future. However, I have since been reassured that this is a one-time deal and thus, will be going with the xslt approach.
Thanks all for your comments/answers!