I have a class (Android Activity) which handles start-up of my application. The application has some pretty complex start-up rules. Right now it looks like a bunch of spaghetti and I'm looking for strategies for refactoring it.
It's honestly such a mess I'm having problems hacking it down to provides pseudo code. In general there are some rules for start-up that are basically codified in logic:
Steps:
Check for error on last exit and flush local cache if necessary
Download settings file
Parse settings and save settings to local native format
Using the values in settings, do a bunch of 'house keeping'
Using a value in settings, download core data component A
Parse component A and load up local cache
During this logic, its also updating the user interface. All of this is handled in a zig-zagging, single monolithic class. Its very long, its got a bunch of dependencies, the logic is very hard to follow and it seems to touch way too many parts of the application.
Is there a strategy or framework that can be used to break up procedural start-up code?
Hmmm. Based on your steps, I see various different "concerns":
Reading and saving settings.
Downloading settings and components (not sure what a "component" is here) from the server.
Reading and instantiating components.
Flush and read cache.
Housekeeping (not really sure what this all entails).
UI updates (not really sure what this requires either).
You might try splitting up the code into various objects along the lines of the above, for example:
SettingsReader
ServerCommunicationManager (?)
ComponentReader
Cache
Not sure about 5 and 6, since I don't have much to go on there.
Regarding frameworks, well, there are various ones such as the previously mentioned Roboguice, that can help with dependency injection. Those may come in handy, or it may be easier just to do this by hand. I think that before you consider dependency injection, though, you need to untangle the code. All that dependency injection frameworks do is to initialize your objects for you -- you have to make sure that the objects make sense first.
Without any more details, the only suggestion that I can think of is to group the various steps behind well structured functions which do one thing and one thing only.
Your 6 steps look to be a good start for the 6 functions your init function should have. If #2 was synchronous (I doubt it), I would merge #2, #3 into a getSettings function.
Related
I have a Feature file and the background step is pretty simple. However, the setup done in that step needs to be working with two different types of values and it is applicable to all the scenarios within that FF. Is there a way we can make this background dynamic?
Example: I want to do as below:
Background:
Given hospital configuration is done using '<some config>'
|some config|
| abc |
|xyz |
There are three ways I can think of to run a feature file twice, one with one configuration and the other with another configuration.
Duplicate the feature file and change the background so that it specifically loads the particular configuration.
Before dismissing this solution look at some of the positives.
its very simple
its easy to document (just put comments in the preamble about the duplication)
it supports customization specific to a particular profile.
The last point is worth expanding on. If the behavior is identical with each profile then what is the point of the profile. Basically you are saying it has no effect at all. If it has not effect at all then why are you testing it. If the behavior varies between profiles then you really want to explore and express those differences.
Run the feature twice by using an external setting.
This basically comes down to having Cucumber pull the setting from the environment and running cucumber twice, once for the first setting, and then again for the second setting.
So something like
SETTING=abc cucumber ...
SETTING=xyz cucumber ...
Use an around hook to run the internals of a scenario twice.
Here you are putting a tag on the feature and making a custom hook to run the scenarios twice. This is equivalent to the second solution but you are embedding the mechanism inside a single run of the features.
In ruby this would look something like
# run_twice_hook.rb
Around(#run_twice) do |scenario, block|
load_first_setting
block.call
load_second_setting
block.call
end
I think this solution comes closest to what the OP wants.
I also think this is the worst solution, because its technical, tricky, hidden and embedded inside the feature run. Its expensive to implement and expensive to maintain, and it probably hides an underlying business problem (mentioned in the first solution)
So please use this solution with a great deal of caution. In general with cuking simple is best, and a bit of repetition is preferable to technical complexity to avoid repetition.
The idea is to utilize AOP for designing applications/tools to debug/view execution flow of an application at runtime. To begin with, a simple data(state) dump at the start and end of method invocation will do the necessary data collection.
The target is not application developers but high level business analyst or high level support people for whom a execution flow could prove helpful. The runtime application flow can also be useful in reducing the learning curve of an application for new developers especially in configuration loaded systems.
I wanted to know if there already exists such tools/applications which could be used. Or better, if this makes sense, then is there a better way to achieve this.
You could start with Spring Insight (http://www.springsource.org/insight) and add your own plugins to collect data appropriate for business analysts/support staff. If that doesn't meet needs, you can write your own custom aspects. It is not that hard.
You could write your own aspects, as suggested by ramnivas, but to prepare for the requests from the users, you may want to just have the aspects compiled into the application, so that you don't have to take a hit at run-time, and then they could just select which execution flows or method groups they are interested in, and you just call the server and set some variable to give them the information desired.
Writing the aspects is easy, but to limit recompiling, you may want to get an idea what the users will want, for example, if they want to have a log of every call made from the time a webservice is called until it gets to the database, then you can build that in, but it would be easier to know this up-front.
Otherwise the aspect does nothing, if the variable is not set, and perhaps unset the variable when finished.
You could also have where they can pick which type of logging and for which user, which may lead to more useful information.
I wonder if I should use it, in this example. I'm reading files, and I need to store one parameter with that file.
According to this parameter I'm bundling files together and sending them over the wire.
I came accross jaf activation framework, and I'm not sure if it is appropriate to use it in such simple example.(store 'file' into DataHandler with this parameter or to make me simple holder). Of course I don't know if requirments can change in the future, and I will need more.
What do you think about it?
My impression is that it's too much, it's difficult to get proper sources. But on the other hand it has what I need.
The question could be more general as well, should I use framework which can do a lot more, if I need something really simple and I can code it quickly?
thanks in advance
To answer your more general question, I would most often make use of frameworks wherever possible.
It's always possible that you're going to want more functionality in that area. If you're using the framework then great. Otherwise you have to back out and rewrite. Or maintain two different implementations.
Frameworks have been debugged/tested etc. and will handle the edge cases. Often what you think of as being trivial ends up more complicated than you first thought.
Don't forget that due to how class loading works, the JVM will only load the classes you require. Consequently you're only affecting the size of deployment of your application, not the runtime size (by referencing a sizable jar)
I am working on a game in JavaFX and I'm sending people the compiled game once in a while for them to try out. As I'm still in the middle of developing it, I have several pieces of code intended solely for developing/debugging.
One example is a gamespeed slider that is of great use for me while testing, but it is VERY buggy and can only be used in a specific manner - in other ways, I don't want code like that in the test releases.
What is the best ways of removing such code?
Surrounding the code with if(Config.DEBUG) (setting a parameter in code) ?
Using if() but setting parameter in different build configurations?
Can SVN branches keep sort of code like this? Or should I change to Git?
Is there any way to use annotations for this?
SVN branches can be used for this, but you keep ending up with the effort of having to merge your branches every so often. I wouldn't do this.
Though perhaps not wildly elegant, I'd go for your first suggestion: Put a configuration parameter somewhere that your build process can change it for you automatically, and if()s around the affected code.
Change your build process so it will create player jars and testing jars at the same time.
Just use pure if statements, and check if some environment variable or VM option is set, in which case execute your debug code (or test release code, depending on your needs). There should be no performance issues, and the HotSpot JIT might even eliminate these parts.
Sure, it feels somewhat quick-and-dirty to me, but it's simple and it does exactly what you need.
Regarding your other suggestions, using a branch is not a good idea to do this. It's possible, but it will have an overhead you don't really like to deal with. Annotations might be able do the job, but this solution will be more complex than necessary.
I'm working on a java SE 1.5+ swing application, in conjunction with others. I'm wondering what the best way of managing string resources is. I understand the principles behind resource bundles etc. I'd like to avoid having one property file for every class that needs a string, as this seems a bit of overkill. Especially when you have a lot of classes that may only make a single reference to a string (say in an error handler). On the other hand it makes it easier when collaborating with others as you reduce the risk of merge conflicts.
It seems particularly cumbersome to have to load resource bundles, every time you need to display simple user feedback, likewise in error handlers, when many classes are involved.
What is the most effective way to manage strings in a fairly large application with hundreds of classes, many of which aren't GUI related, but need to pass informative messages back up to the GUI when exceptions occur.
I'm using NetBeans which generally creates a property file for each GUI class, for all text relating to buttons, labels etc.
What makes you think you have to have a separate properties file for every class? Generally you only need a few (or just one!) properties file (per language, of course).
Just call ResourceBundle.getBundle() with appropriate parameters - you can use the same bundle from multiple classes.
EDIT: Having one set of property files per dialog etc makes it easier to see where any particular string is coming from, but it makes it harder to reuse the same messages etc. Quite where the right balance is will depend on the application.
JSR 296 Swing Application Framework has support for resource management (and it looks like will be part of Java 7). SAF aims to pre-build parts of a Swing app that many people frequently need while encapsulating best practices. You probably don't want to tie to it directly but its worth taking a look at what they do to see whether it gives you some ideas. If I recall, they use cascading resource bundles with well-defined naming conventions. The latter means you know where to look and the former means that you can reuse properties across some portion of your package hierarchy.
Many JSR 296 resources collected here.
This may be naive, but what about storing them in a database, either embedded or external? This might simplify management, and changing languages more configurable.
I'm going to implement something similar to Launchpad's translation platform this year:
https://launchpad.net/+tour/translation
In a nutshell:
Concurrent translation
Phrase suggestions based on previously-entered phrases
Policies, e.g. Partly restricted and structured: anyone can suggest translations, while trusted community members review and approve new work
UPDATE
Of course, this builds on top of ResourceBundle etc, but is a nice way to manage all them strings ;-)