I am currently writing an application using Drools 5.0. This application seems to be running a little slow, but I have a theory why. This application receives many updates for facts already in stored in the knowledge session. The Drools update function under the hood really does a retraction then an insertion. This application has over 200 rules. Some of the rules are written to fire when certain facts are removed. Other rules are written to fire when certain facts are asserted into the knowledge session. Since update really does a retraction then insertion will the retraction and insertion related rules still fire during an update? Even though nothing is really being 'inserted' or retracted from the knowledge session?
One thing to note, I 'hooked' up the WorkingMemoryFileLogger to my knowledge session to get a better idea about whats going on. That's when I saw lots of unexpected retraction/insertion rule-activation creations being added to the Agenda, but it seems they don't ever get activated. It seems to me that updating facts can be expensive especially based on your fact model, and should me used sparingly. Is this correct?
I think you have understood it correctly. An update is kind of like a retract plus an assert.
The first thing to be sure of is if your rules are giving you what you want - ie do it work but you just want to improve performance?
In some ways you can think of an update (and also checkout the "modify" keyword..) as part of the evils of immutability ;) When you update - you tell the network that the fact has changed, but it doesn't yet track it at a field level (that is TBD) so it may cause more work then is necessary as all these activations are created that are not really needed (as they are using fields that didn't actually change in value).
Hard to be more specific - if you provided some sample rules/fact model (if you can in a safe way of course !) we might be able to suggest some ideas to break it down to be more granular.
Good luck !
The best way to know is to profile the app and find out exactly what's happening. Use something like OptimizeIt or JProbe in combination with the jvisualvm.exe that ships with JDK 1.6. Don't guess - get more data.
In my experience, the update() method is only necessary if you need an entity to be reevaluated by the WHERE clause within the context of the currently executing rule. Since the RETE evaluation happens all at once upon entry of the rule, removing some update() statements (where possible) will speed it's execution. Sometimes this involves setting some flags and postponing the real update() until a later rule. You can also put some of the evaluation of the current entity states into an if statement in the THEN clause, using the WHERE clause for more basic filtering.
Related
The IDE has suggested to add a getter/setter to a private field.
It is never used, and reaching the field is only from within the class.
what is the preferred coding style? keeping the never used methods?
Im asking specifically about java/kotlin but this is a general question
There are a few distinctions that you need to know about to answer this question yourself - as it depends on a ton of things; far too much to ask for and for you to write down:
For this entire answer it's important to think about the distinction between layers of code. These layers can be a bit hard to think about if the project you're imagining when thinking about layers is something small and written just by yourself. So don't do that - think about, say, Microsoft Word as a product. It's written by many people, over many years - entire departments and dev teams. It's somewhat modular (there's the "Mail Merge" system that doesn't interact, at all, with the 'show available fonts' dropdown).
What's the whole private fields, public getters/setters all about in the first place?
Fields are highly inflexible constructs. If you 'expose' them (make it public), then there is no granularity available to you. The only knobs you can twiddle with is:
You can make a field unchangable for everybody - you can't change it, nor can anybody else. (To do this, mark it final).
That's it. You can't do anything else 'to' it. You can't have more fine grained control about access (such as allowing code 'nearby' to change it, but not code further out), you can't run some code as field writes/read happen either. Perhaps you need more granularity. Keep in mind that we're trying to wrote code that will survive 10 years in an environment with 100 programmers, most of whom won't last the entire 10 years, in many different teams. So, imagine you wanted to:
Make it a field that everybody gets to read, but only 'your' code (that is, the programmers working on this particular corner of the codebase who are aware of this particular corner's rules and needs) should get to change.
Make it a field that everybody gets to read, and write, but, if its not 'your' code doing the writing, a log line should be emitted.
Make it a field that nobody gets to write (not even you - it is initialized at object creation, that's it, makes it easier to reason abou, that's why we 'handcuff' ourselves: When you need to maintain code for 10 years, limiting certain things off and having a compiler that enforces these is quite useful), and 'outsiders' can read, but you want to tweak the read a bit, for example, substitute 'the current date' when the value is blank.
And so on.
Even more importantly, is time: Sometimes you start out just wanting to expose a field to everybody right now, but later on you realize: Oh, wait, we need to emit a log line. Or: Oops, we need to return the current date if the value is blank.
If you just make a field public, you:
Do not have any of that granularity.
Even if you're okay with that now, you can't later on update your code and add stuff that needs this granularity; not without turning the field into a getter/setter pair, and that is not backwards compatible: You need to send a mail to those 100 developers or start refactoring their code which is a huge undertaking.
Hence, even if you don't see any point or purpose in giving you the granularity powers right now, it's still advised to just make that field private and add getters and setters: That way if later on some currently not forseeable request comes in (such as: Log the writes to this field, please!), you can add that feature without having to ask all other 100 developers to pull the change and edit all their branches, which is a huge undertaking.
YAGNI
A maxim in the programming world is YAGNI - You aren't gonna need it.
YAGNI is a dangerous beast - it applies -solely- to semi-local endeavours.
The basic principle of YAGNI is: Code is a flowing concept, and you should never hesitate to make improvements, especially if you can't think of a way this would break any existing usage. Hence, given that your development processes should be set up such that adding stuff is easy, don't add stuff until you need it - after all, if you add stuff even if you don't currently need it, maybe you never need it and you're now just clogging up the code for no good reason. IF somebody needs it, they can trivially add it then.
The problem with YAGNI is that predicate: YAGNI is based on the notion that making a change is quick and painless.
Imagine this scenario: The Microsoft Office development crew decides to write their own font rendering system, because what windows delivers just looks bad on HiDPI screens. So, they spend a ton of time and research on this and with much fanfare release a new version. Everybody loves it.
The OS team comes aknocking and the MS Office team decides to 'hand over' the new font rendering engine to the OS team. In order to avoid having 2 teams spend the resources on maintaining it, the next version of MS Office is pegged to only run on a new version of the OS that includes the new pipeline, and thus, the MS Office team removes the font rendering engine from it - it's now the OS's job.
Whoops, any YAGNI is now quite a big problem: If there's something foreseeable and obvious the MSOffice team needed that they didn't add (or if the Windows OS team applied YAGNI to the API they expose to apps to do font rendering stuff), then the MS Office team needs to give a call to the Windows OS team that's in another country, working on other source control, and having entirely different versioning pipelines, and ask them for a change. It'll take 2 years before it's all said and done.
Linters/stylcheckers are tools, and fairly stupid ones at that
Any warning about style or suggestion about changes are just that - suggestions. These tools aren't perfect, and will absolutely suggest very silly things from time to time. You should never apply style advice until you understand why it is given and under what circumstances it should be followed, and you should feel free to tell linters/stylecheckers to buzz off if they are wrong.
Some dev shops put out absolutist rules ('you can NEVER check in code that fails our linter tool - we have git commit hooks that enfore this!'), but those shops are misguided: They seem to think that if only you rigorously apply enough style rules, that code will therefore be well written, bug free, and performant. This is obviously entirely false. You should absolutely help programmers (and might lightly enforce this even) to help themselves and avail themselves of the tools available to write better code, but you can't beat the bird to make it sing, so to speak.
Thus, be aware that sometimes the best thing to do about a style suggestion - is to ignore it.
Back to your question
So, now you know what I'm driving at when I ask these questions, which naturally lead you to answering your own question:
Is the field even meant to be exposed in the first place? Anything you 'expose' is likely to be used by code that's relatively far removed from you (different team, different time, different context), and once you expose it, you have to continue to support it - any changes you make can't fundamentally change/remove what you exposed. So, perhaps just having a private field with no getters and setters is the best place to start:
If you're sure it makes no sense to expose it, then don't. Just leave them as private fields, the code in this source file can edit them, and other code cannot even assume this field exists - they should know nothing about it.
If you're sure it makes perfect sense to expose it; it is the very point of the class, then make a private field with public getter (and if you want, setter - do you intend for it to be mutable or not?) - even if you don't see any need to do special stuff in that getter. Java programmers expect to access properties from other source files via getters and setters and you keep the flexibility to change things later without breaking compatibility.
If you're not sure, then think about YAGNI: Is this an API that is going to be exposed so far and wide it'll affect people who cannot easily modify the codebase? Then, sorry, you're going to have to think some more and make a decision. But most likely you're not writing that kind of code, and anybody who might want to access this thing could change the code fairly easily: It'll be you, or a colleague working in the same source tree. In which case, don't think about it too long - err on the side of caution and don't make getters and setters. If someone needs em later, well, let them make the call - with the benefit of that use case they now have, they'll be more likely to make a well informed decision than you can, without that benefit.
This is one of the questions that involves crossing what I call the "Hello World Gulf" I'm on the "Hello world" I can use SQLite and Content Providers (and resolvers) but I now need to cross to the other side, I cannot make the assumption that onUpgrade will be quick.
Now my go-to book (Wrox, Professional Android 4 development - I didn't chose it because of professional, I chose it because Wrox are like the O'Reilly of guides - O'Reilly suck at guides, they are reference book) only touches briefly on using Loaders, so I've done some searching, some more reading and so forth.
I've basically concluded a Loader is little more than a wrapper, it just does things on a different thread, and gives you a callback (on that worker thread) to process things in, it gives you 3 steps, initiating the query, using the results of the query, and resetting the query.
This seems like quite a thin wrapper, so question 1:
Why would I want to use Loaders?
I sense I may be missing something you see, most "utilities" like this with Android are really useful if you go with the grain so to speak, and as I said Loaders seem like a pretty thin wrapper, and they force me to have callback names which could become tedious of there are multiple queries going on
http://developer.android.com/reference/android/content/Loader.html
Reading that points out that "they ought to monitor the data and act upon changes" - this sounds great but it isn't obvious how that is actually done (I am thinking about database tables though)
Presentation
How should this alter the look of my application? Should I put a loading spinning thing (I'm not sure on the name, never needed them before) after a certain amount of time post activity creation? So the fragment is blank, but if X time elapses without the loader reporting back, I show a spiny thing?
Other operations
Loaders are clearly useless for updates and such, their name alone tells one this much, so any nasty updates and such would have to be wrapped by my own system for shunting work to a worker thread. This further leads me to wonder why would I want loaders?
What I think my answer is
Some sort of wrapper (at some level, content provider or otherwise) to do stuff on a worker thread will mean that the upgrade takes place on that thread, this solves the problem because ... well that's not on the main thread.
If I do write my own I can then (if I want to) ensure queries happen in a certain order, use my own data-structures (rather than Bundles) it seems that I have better control.
What I am really looking for
Discussion, I find when one knows why things are the way they are that one makes less mistakes and just generally has more confidence, I am sure there's a reason Loaders exist, and there will be some pattern that all of Android lends itself towards, I want to know why this is.
Example:
Adapters (for ListViews) it's not immediately obvious how one keeps track of rows (insert) why one must specify a default style (and why ArrayAdapter uses toString) when most of the time (in my experience, dare I say) it is subclasses, reading the source code gives one an understanding of what the Adapter must actually do, then I challenge myself "Can I think of a (better) system that meets these requirements", usually (and hopefully) my answer to that converges on how it's actually done.
Thus the "Hello World Gulf" is crossed.
I look forward to reading answers and any linked text-walls on the matter.
you shouldnt use Loaders directly, but rather LoaderManager
It's a very specific problem I have:
I'm working on a text-based RPG, where the main work is to implement an editor, that gives the possibility to add NPCs, Items and place them on the map (...) without any knowledge about programming.
All of these things work fine with doing some SQL queries and the whole thing already works. Now I'm working on quest editing. My basic concept is, that every time the player enters a command, a database entry for the specific string is queried, that's linked to a set of conditions and actions, which have unique IDs. Those are queried in the java code, where a specific condition (e.g. that the players money equals 100) has a part of code that returns the result. This means, that hundreds (or more) IFs have to be passed, each time a command is entered - same with the actions according to the command. I'm not even sure if that is the right way (If anyone has a propose to this, feel free to post).
The point is now, that quests basically consist of quest stages, which also have conditions to be enabled and actions, performed when enabled. That means, that also with each entered command, all of these queries have to take place. I thought about using some kind of trigger, but I don't have a good idea how to implement it, because I don't really want to edit java code out of this editor. I also considered using prolog, but also in that case I'd have to add triggers into java code I guess.
I know that this is a little bit hard to handle in a forum like this, but if anyone has a suggestion, I'd be really glad.
EDIT:
As suggested in a comment, I'd like to shorten the whole thing: If any command (out of houndres or thousands) could trigger one particular quest/quest stage (out of thousands) and these triggers should be set with an editor, what's a proper way to implement that?
reasoning over lots of facts and triggering actions when a set of facts matches specific conditions is a good match for drools.
you could represent every action/decision that the player has made as a fact, which you could insert into a drools knowledge session.
in that session you could store all of your "triggers" as drools rules, which will fire when a collection of facts in memory match the condition.
drools supports dynamic addition/removal/editing of rules and is explicitely targeted at allowing non-developers to write logic using a simpler rule language.
the specific part of drools to start with is the core - drools expert
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've been using Sonar code quality management platform for some time, and for the most cases I find it very helpful in revealing hidden design flaws of my code base.
However, there's one rule that gives me more annoyance than help and that is its check for 'cyclic package reference' violations.
I guess I fully understand where such a dependency between packages is a bad thing. For example, in a typical 3-tier presentation/service/persistence layered design, it's almost always a bad idea to let the database handling code have a reference back to UI related classes. I have no problem with calling it a 'violation'.
But let's consider other cases, i.e. like designing an IDE-like application. Say, we have a main package which contains an Application interface, which defines List<View> Application.getViews() method to reference application's views.
However, when the View interface has an Application getApplication() method to refer back to its parent application, which I believe is a quite common design, it will introduce a cyclic reference, provided each of the interfaces are separated in com.myapp.ui, and com.myapp.ui.view respectively.
Of course, you can just put the View interface into the com.myapp.ui to break the cycle. But when you have various other view related APIs in com.myapp.ui.view, many of them another abstract APIs like AbstractView, ContentView, AbstractContentView, etc. I wonder if it's more advisable to keep them in separate packages for a management purpose.
And consider the said application has many other similar cases like com.myapp.ui.action, com.myapp.ui.perspective, etc. which would really make com.myapp.ui package crowded if we are to put them all in there.
So, what approach do you suggest to handle such a situation? Are really every cyclic package references a bad thing? Or if I have to live with them, how do you configure Sonar to check only real, problematic cycles?
Every absolute -- except this one ;) -- is going to be wrong some of the time. So, is every cyclic reference bad? No. You have to use your judgement.
But if you do introduce a cyclic dependency, it's worth asking if you really need it, and why. The tl;dr is that more often than not, you may find that breaking the cycle can improve your modularity, and in particular your ability to test components separately.
To use your example, does a view really need a getApplication(), which presumably returns a relatively "heavy" object (ie, one that itself needs a database, network, etc etc)? Maybe... but maybe not. If what you really need from that getApplication is something with a few callbacks (such as when a user initiates some action), then it could be useful to create an interface in some common package for that callback. So, rather than:
com.foo.app.Application
com.foo.view.View
Application getApplication()
You'd have:
com.foo.common.Callback // maybe just a Callable, Runnable, etc?
com.foo.app.Application
provides a Callback for some action foo
com.foo.view.View
Callback getFooCallback()
The question you should be asking is: what does that give me? It could be that you have to stub out so much that it doesn't give you much -- though that may suggest you can break apart your classes some. But it could be that it actually makes it easier to test your view, because now your unit test can (1) test the view without spinning up a whole application, and (b) provide a "dummy" callback that does something like saving a string that describes the action, and then your unit test asserts that it saved the right string.
And indeed there is an open JIRA ticket to prevent considering a cycle between father/child packages as a quality flaw : http://jira.codehaus.org/browse/SONAR-3452
We've got a fairly large amount of code that just made the jump to Java 5. We've been using generics in those components targeted at being released in the Java 5 version, but the remaining code is, of course, full of raw types. I've set the compiler to generate an error for raw types and started manually clearing them, but at the present rate it'll take a very long time to go through with it (there are about 2500 errors). And that's with Eclipse's helpful Infer Generic Type quick fix, which always gets rid of the errors, but often generates code that needs further work.
Is there any better way to dealing with this? Are there any automated tools better than Eclipse? Any way to apply the refactoring to all occurences instead of doing them one-by-one? Or do you just ignore the warnings?
I would suggest ignoring the warnings. Otherwise, you'll be putting a lot of time into updating the legacy code without making any improvements to its functionality.
Update: Great comment from Luke that I thought should get more visibility:
"Generics are a way to catch run time bugs at compile time. Unless this legacy code has bugs in it that you think are related to casting I would leave it alone (if it ain't broke, don't fix it)"
As far as I know, you're going about it as efficiently as possible. It's
obviously not perfect, but you'll finish eventually.
I recommend that you do it in stages, however; there are likely parts of the
code that would benefit more from this than others, focus on those. Trying to
do it all in one sweep runs the risk of introducing new bugs to your code. We
have one such place where we have a collection that holds context-dependent
data, and generics actually can't work for it.
Basically, do what you're doing, but do it in stages as part of other work,
instead of trying to fix it all in one throw.
Faced with a similar challenge, we opted to upgrade to Java 5 style generics only in the code that was edited for another reason. So if you have a bug to fix in DoItFast.java, update DoItFast.java to use Java 5 style generics. The areas of the code that are being edited and changed regularly will get updated quickly. After a few weeks or months of this behavior, you can reevaluate the condition of your code base.
If that doesn't get the job done fast enough for you, sometimes I'll use the slow time after lunch to just mindlessly cleanup a few classes and speed the process along.
I don't think it is necessary to update all the old code. Maybe if you could somehow identify which parts of the old code are used frequently, and only update those to use generic types? Or maybe you could only worry when the raw type is returned from a public function? A lot of these cases are probably just private/local variables, which are already written without generic types and presumably work just fine, so it's probably not worth the effort to rewrite them.
I understand with IDEA you can select all your classes, popup the context menu and select Refactor | Generify. Job done. It's certainly a more enjoyable experience to work with generified code (IMO).