Java delaying return of variable - java

How can I delay returning a varaible from a method in Java, or how should I do it if it is something unwanted to do?
Consider this:
public class Transaction {
public int addInsert() {
...
return insertId;
}
public boolean addUpdate() {
...
return updateSuccesful;
}
public void commit() {
/* Calls everything that is inserted via addInsert or addUpdate. */
}
}
Now assume you use the code as:
Transaction transaction = new Transaction();
int insertedId = transaction.addInsert();
boolean updateSuccesful = transaction.addUpdate();
//insertId, updateSuccesful cannot be known yet
transaction.commit();
//now insertId, updateSuccesful should be filled in
So the return may only happen if transaction.commit() has been called.
Any thoughts?

You can achieve this functionality by multithreading and making the threads that are running those two methods .wait() until the commit() method calls .notify() to let them know that they can finish.
However, a better way to structure this is to re-organize your your methods, perhaps by making commit return the insertedID and make it return -1 if it is unsuccessful. That way you can check the boolean by seeing if it is -1 or not, and you can read the ID by reading the return of commit.

You're example looks like the Unit of Work Pattern: http://martinfowler.com/eaaCatalog/unitOfWork.html
Which also shows the answer to your question.
You can't actually call method a, and have it's return value delayed until you call method b without getting into threading, and that's still going to be an overly complicated and very brittle solution to the problem.
Instead call method a, method b etc. However don't actually do the work until the commit happens. Then the commit returns, or you can call a getMethodAStatus() etc.

Related

Elegant way to return variable before new variable assignment?

This might sound like a dumb question, because it might be no other way to do this. After designing my own list, this sort of "issue" came up in multiple occasions. To clarify, I have a problem with returning a cached variable after assigning new value to the original variable. Here's an example:
public T next() {
final Node<T> thisNode = posNode;
posNode = posNode.getNext();
return thisNode.getData();
}
This might seem like a non-issue, but occasionally multiple variables has to be cached before returning a valid value. I do not really like it, because personally I think it reduces the code's readability, especially when caching multiple variables.
Is there another way to write this code while maintaining its functionality? Basically a way to assign a new value to a variable after the return statement:
public T next() {
return posNode.getData();
posNode = posNode.getNext();
}
Thanks! :)
The second way is not possible as the code is not reachable after return. And your first way is the best way far you to achieve what you are looking for and it is not code smell. Often they refer as temp variables. Use them and better convey a message to the code reader by better naming convention. For ex tempPosNode
An elegant (but with some cognitive dissonance) option is a dummy method.
public static <T> T first(T first, Object... theRest) {
return first;
}
public T next() {
return first(posNode.getData(), posNode = posNode.getNext());
}
You can use a finally block to execute it, but it will execute even after exceptions:
public T next() {
try {
return posNode.getData();
} finally {
posNode = posNode.getNext();
}
}

Should exceptions be used to unwinding process back to main?

Now this is really quite difficult for me to explain so please bear with me.
I've been wondering as of late the best way to "unwind" every chained method back to a main method when certain circumstances are met. For example, say I make a call to a method from Main and from that method I call another one and so on. At some point I may want to cancel all further operations of every method that is chained and simply return to the Main method. What is the best way to do this?
I'll give a scenario:
In the following code there are 3 methods, however when Method1 calls Method2 with a null value it should unwind all the way back to Main without further operations in Method2 (EG the "Lots of other code" section).
public static void main(String[] args)
{
try
{
Method1();
}
catch( ReturnToMainException e )
{
// Handle return \\
}
}
public static void Method1() throws ReturnToMainException
{
String someString = null;
Method2( someString );
// Lots more code after here
}
public static boolean Method2( String someString )
{
if( someString == null )
throw new ReturnToMainException();
else if( someString.equals( "Correct" ))
return true;
else
return false;
}
In this example I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue, but when dealing with methods that can only return True/False I find I don't have enough options to return to decide on an action. I guess I could use Enumerators or classes but that seems somewhat cumbersome.
I use a throw which I've read should only be used in "Exceptional Circumstances". I often run into this issue and find myself simply doing If/Else statements to solve the issue
Exception throwing is relatively expensive so it should not be used without careful thought but I believe that your example is a ok example of proper usage.
In general, you should use exceptions only for "exceptional" behavior of the program. If someString can be null through some sort of user input, database values, or other normal mechanism then typically you should handle that case with normal return mechanisms if possible.
In your case, you could return a Boolean object (not a primitive) and return null if someString is null.
private static Boolean method2( String someString ) {
if (someString == null) {
return null;
}
...
}
Then you would handle the null appropriately in the caller maybe returning a boolean to main based on whether or not the method "worked".
private static boolean method1() {
...
Boolean result = method2(someString);
if (result == null) {
// the method didn't "work"
return false;
}
Then in main you can see if method1 "worked":
public static void main(String[] args) {
if (!method1()) {
// handle error
}
...
}
Notice that I downcased your method names and changed the permissions of your methods to private both which are good patterns.
Enumerators or classes but that seems somewhat cumbersome.
Yeah indeed. It depends a bit on how this code is used. If it is a API method that is called by others, you might want to return some sort of Result class which might provide feedback like a boolean that the argument was null. Or you might throw an IllegalArgumentException in that case. Instead, if this is an internal local private method, then I'd vote for a simpler way of handling argument errors. Either way I'd use javadocs to document the behavior so you don't trip up future you.
Hope this helps.

Methods vs Method assigned to variables in Java

I'm sort of confused, I guess this question is just a matter of preference, I just want to understand the difference of the following code.
if (IsRegistered() == true) ...
public boolean IsRegistered()
{
private boolean status = false;
// blah blah code here
return status;
}
vs
isRegistered = IsRegistered();
if (isRegistered)
I know both would work, I'm not being pedantic but I just want to understand so I would know my way around.
if (isRegistered() == true) ...
This is verbose since you know if it returns true it will do it, if not, it wont. So its the same as doing:
if (isRegistered()) ...
What it does, its just getting the returning boolean value from the method and checking the condition in the if statement.
Now if you wanted to check the boolean value again, you would need to re-call the method (which may have to do something complex to return that value), BUT if you assign it to a variable first and then check the condition, like this:
boolean isRegistered = isRegistered();
if (isRegistered)...
Later on the code you can just do it again without calling that method again.
if (isRegistered)... // n lines later.
hence, avoiding executing the process again.
At the end of the day, it pretty much depends on what you need to do.
When you invoke a method which has a non-void return type, the method itself resolves to a value the same way that using a variable does. You can either use that value directly or assign it to a variable and use that.
Just use:
if ( IsRegistered() )
It's the most readable code. Having a variable to "unbox" the method will not do any good; the compiler picks it up and replaces it into the control code itself in an internal optimization pass.
Also, the performance of your IsRegistered() method, when the self-optimization of machines is put aside, depends on how your "my code here" works:
source : {
private boolean status = false;
// blah blah code here
return status;
}
optimization-passed : {
return false; // When internal code does not modify "status"
preturn _status; // When internal code modifies "status"
}

Best approach to refactor this java snippet

I was told it is not a good style to call potentially costly methods for boolean expressions (getSupercategories()).
private final SuperCategoriesResolver<ProductModel> catResolver = new SuperCategoriesResolver<ProductModel>() {
#Override
public Set<CategoryModel> getSuperCategories(final CategoryModel item) {
return item == null || item.getSupercategories() == null ? Collections.EMPTY_SET
: new LinkedHashSet<CategoryModel>(
item.getSupercategories());
}
};
As well that getSupercategories() is potentially dangerous since it's backed by a relation attribute which might not be coming from local data members (item is sent as a parameter to a public method in this class and after wards is sent to getSuperCategories() which is overriden in the same class when declaring catResolver).
Is this a better approach to tackle the argument above?
private final SuperCategoriesResolver<ProductModel> catResolver = new SuperCategoriesResolver<ProductModel>() {
#Override
public Set<CategoryModel> getSuperCategories(final ProductModel item) {
if (item != null) {
Set<CategoryModel> superCategories = (Set<CategoryModel>) item
.getSupercategories();
if (superCategories != null)
return superCategories;
}
return Collections.EMPTY_SET;
}
};
Where I first verify that item is not null. if it is, then a return empy_set if not then I called the costly method and get the collection and just if it is not null return the collection with elements.
Thank u very much for your advice.
It is likely to get more efficient to call getSupercategories() once instead of twice if it does any computation.
Do you need to return a copy of this set? You do in the first example but not the second.
Second approach is indeed faster because there is only one call to the getSupercategories method if item is not null. However, in your second approach, you no longer create a LinkedHashSet instance -- which means it will behave differently (though faster).
This sounds more like performance optimization as opposed to refactoring. Usually when you refactor something, there is a "factor" in there somwhere, that trims the code down by eliminating redundancies.
Nulls are your problem. Can you make a refactoring to push nulls away?
For example, you could refactor your code to make item.getSuperCategories never return null? Or do you need to distinguish between the empty set and null?
Similarly, why are you passing null into this method? If you can eliminate that scenario then the code just becomes a one liner.

Verifying partially ordered method invocations in JMockit

I'm trying to write a unit test (using JMockit) that verifies that methods are called according to a partial order. The specific use case is ensuring that certain operations are called inside a transaction, but more generally I want to verify something like this:
Method beginTransaction is called.
Methods operation1 through to operationN are called in any order.
Method endTransaction is called.
Method someOtherOperation is called some time before, during or after the transaction.
The Expectations and Verifications APIs don't seem to be able to handle this requirement.
If I have a #Mocked BusinessObject bo I can verify that the right methods are called (in any order) with this:
new Verifications() {{
bo.beginTransaction();
bo.endTransaction();
bo.operation1();
bo.operation2();
bo.someOtherOperation();
}};
optionally making it a FullVerifications to check that there are no other side-effects.
To check the ordering constraints I can do something like this:
new VerificationsInOrder() {{
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
}};
but this does not handle the someOtherOperation case. I can't replace the unverifiedInvocations with bo.operation1(); bo.operation2() because that puts a total ordering on the invocations. A correct implementation of the business method could call bo.operation2(); bo.operation1().
If I make it:
new VerificationsInOrder() {{
unverifiedInvocations();
bo.beginTransaction();
unverifiedInvocations();
bo.endTransaction();
unverifiedInvocations();
}};
then I get a "No unverified invocations left" failure when someOtherOperation is called before the transaction. Trying bo.someOtherOperation(); minTimes = 0 also doesn't work.
So: Is there a clean way to specify partial ordering requirements on method calls using the Expectations/Verifications API in JMockIt? Or do I have to use a MockClass and manually keep track of invocations, a la:
#MockClass(realClass = BusinessObject.class)
public class MockBO {
private boolean op1Called = false;
private boolean op2Called = false;
private boolean beginCalled = false;
#Mock(invocations = 1)
public void operation1() {
op1Called = true;
}
#Mock(invocations = 1)
public void operation2() {
op2Called = true;
}
#Mock(invocations = 1)
public void someOtherOperation() {}
#Mock(invocations = 1)
public void beginTransaction() {
assertFalse(op1Called);
assertFalse(op2Called);
beginCalled = true;
}
#Mock(invocations = 1)
public void endTransaction() {
assertTrue(beginCalled);
assertTrue(op1Called);
assertTrue(op2Called);
}
}
if you really need such test then: don't use mocking library but create your own mock with state inside that can simply check the correct order of methods.
but testing order of invocations is usually a bad sign. my advice would be: don't test it, refactor. you should test your logic and results rather than a sequence of invocations. check if side effects are correct (database content, services interaction etc). if you test the sequence then your test is basically exact copy of your production code. so what's the added value of such test? and such test is also very fragile (as any duplication).
maybe you should make your code looks like that:
beginTransaction()
doTransactionalStuff()
endTransaction()
doNonTransactionalStuff()
From my usage of jmockit, I believe the answer is no even in the latest version 1.49.
You can implement this type of advanced verification using a MockUp extension with some internal fields to keep track of which functions get called, when, and in what order.
For example, I implemented a simple MockUp to track method call counts. The purpose of this example is real, for where the Verifications and Expectations times fields did not work when mocking a ThreadGroup (useful for other sensitive types as well):
public class CalledCheckMockUp<T> extends MockUp<T>
{
private Map<String, Boolean> calledMap = Maps.newHashMap();
private Map<String, AtomicInteger> calledCountMap = Maps.newHashMap();
public void markAsCalled(String methodCalled)
{
if (methodCalled == null)
{
Log.logWarning("Caller attempted to mark a method string" +
" that is null as called, this is surely" +
" either a logic error or an unhandled edge" +
" case.");
}
else
{
calledMap.put(methodCalled, Boolean.TRUE);
calledCountMap.putIfAbsent(methodCalled, new AtomicInteger()).
incrementAndGet();
}
}
public int methodCallCount(String method)
{
return calledCountMap.putIfAbsent(method, new AtomicInteger()).get();
}
public boolean wasMethodCalled(String method)
{
if (method == null)
{
Log.logWarning("Caller attempted to mark a method string" +
" that is null as called, this is surely" +
" either a logic error or an unhandled edge" +
" case.");
return false;
}
return calledMap.containsKey(method) ? calledMap.get(method) :
Boolean.FALSE;
}
}
With usage like the following, where cut1 is a dynamic proxy type that wraps an actual ThreadGroup:
String methodId = "activeCount";
CalledCheckMockUp<ThreadGroup> calledChecker = new CalledCheckMockUp<ThreadGroup>()
{
#Mock
public int activeCount()
{
markAsCalled(methodId);
return active;
}
};
. . .
int callCount = 0;
int activeCount = cut1.activeCount();
callCount += 1;
Assertions.assertTrue(calledChecker.wasMethodCalled(methodId));
Assertions.assertEquals(callCount, calledChecker.methodCallCount(methodId));
I know question is old and this example doesn't fit OP's use case exactly, but hoping it may help guide others to a potential solution that come looking (or the OP, god-forbid this is still unsolved for an important use case, which is unlikely).
Given the complexity of what OP is trying to do, it may help to override the $advice method in your custom MockUp to ease differentiating and recording method calls. Docs here: Applying AOP-style advice.

Categories