Would you use the Action delegate to avoid duplication of code? - dry

I just asked a question that helps about using generics (or polymorphism) to avoid duplication of code. I am really trying to follow the DRY principle.
So I just ran into the following code...
Sub OutputDataToExcel()
OutputLine("Output DataBlocks", 1)
OutputDataBlocks()
OutputLine("")
OutputLine("Output Numbered Inventory", 1)
OutputNumberedInventory()
OutputLine("")
OutputLine("Output Item Summaries", 1)
OutputItemSummaries()
OutputLine("")
End Sub
Should I rewrite this code to be as follows using the Action delegate...
Sub OutputDataToExcel()
OutputData("Output DataBlocks", New Action(AddressOf OutputDataBlocks))
OutputData("Output Numbered Inventory", New Action(AddressOf OutputNumberedInventory))
OutputData("Output Item Summaries", New Action(AddressOf OutputItemSummaries))
End Sub
Sub OutputData(ByVal outputDescription As String, ByVal outputType As Action)
OutputLine(outputDescription, 1)
outputType()
OutputLine("")
End Sub
I realize this question is subjective. I am just wondering about how religiously you follow DRY. Would you do this?
Seth

I've seen this called the "Hole in the middle" pattern. The "Real World Functional Programming" book mentions it. Here's a link.
http://enfranchisedmind.com/blog/posts/the-hole-in-the-middle-pattern/
See, there’s a pattern I’ve gotten
used to in Ocaml- and I’d even used it
in Perl, which I think of as the “hole
in the middle” pattern. The basic idea
is that you have two pieces of code
that are almost exactly identical,
except for that little middle part
there. The idea is that you factor out
the common code into a single
function, which takes a function
pointer as an argument. The middle
part in the shared code is replaced by
a call to the function pointer, and
the two places which are being
combined simply call the combined
function with a pointer to a function
that contains the unique part.

I wouldn't say I use it all the time, but I have used Action delegate to avoid code duplication. One scenario where I have used it is to wrap WCF calls (inside a client proxy) to avoid the same boiler plate code.
private void InvokeAndHandleFaults(
Action<Data, Context> wcfCall,
Data data,
Context context)
{
bool isSuccess = false;
try
{
wcfCall(data, context);
if (this.ChannelFactory.State != System.ServiceModel.CommunicationState.Faulted)
{
this.ChannelFactory.Close();
}
isSuccess = true;
}
catch (FaultException ex)
{
HandleFault(ex);
}
finally
{
if (!isSuccess)
{
this.ChannelFactory.Abort();
}
}
}
In terms of the example in the question, I would probably not use an Action. I would definitely not refactor to use an Action. Mainly because the actual logic is quite simple so I don't see much benefit. As the "complexity"/size of the repeated code increased I would be more likely to use a delegate.

Related

Kotlin use block function is not called on File.printWriter()

I'm new to Kotlin and I'm trying to do a simple task - create and write to a file. For some reason, using use() with a block function on printWriter() doesn't actually write.
File("test2.txt").printWriter().use { out ->
{
println("hmmm")
out.println("what's up")
log.info { "finished writing" }
}
}
In fact, the block function doesn't seem to be called at all - both "hmmm" and "finished writing" never show up, although the file itself is created (but is totally empty).
The much simpler writeText() works just fine - the file is created and the given text is written to the file.
File("test3.txt").writeText("testing")
What am I doing wrong in my use() version?
Edit: it seems to be a syntax issue with my block function. Looks like I have an extra pair of brackets? Would love a brief explanation as to why it makes it not work.
Edit 2: I think I understand now. The way I wrote it, I was essentially returning the block function itself rather than running through it.
So the problem was that the way I was writing the block function caused it to just return the inner block function, and not actually call it.
Here are two ways that work:
File("test2.txt").printWriter().use {
println("hmmm")
it.println("what's up")
log.info { "finished writing!" }
}
File("test2.txt").printWriter().use(fun(out) {
println("hmmm")
out.println("what's up")
log.info { "finished writing!" }
})
Although, for my purposes writeText() actually works just fine and is much shorter haha.

Extraordinary uses of Exceptions vs OOP rules

Me and my friend have some arguement about Exceptions. He proposes to use Exception as some kind of transporter for response (we can't just return it). I'm saying its contradictory to the OOP rules, he say it's ok because application flow was changed and information was passed.
Can you help us settle the dispute?
function example() {
result = pdo.find();
if (result) {
e = new UniqueException();
e.setExistingItem(result);
throw new e;
}
}
try {
this.example();
} catch (UniqueException e) {
this.response(e.getExistingItem());
}
Using exceptions for application flow is a misleading practice. Anyone else (even you) maintaining that code will be puzzled because the function of the exception in your flow is totally different to the semantic of exceptions.
I imagine the reason you're doing this is because you want to return different results. For that, create a new class Result, that holds all information and react to it via an if-statement.

how to avoid recursive calls with byte buddy - java.lang.StackOverflowError

I have an advice which calls a similar method in the advice. How do we make sure the advice gets called once and only once. Right now as the method I am calling within advice is the same as the one being instrumented, it goes into recursive calling and results in java.lang.StackOverflowError.
transform(
new AgentBuilder.Transformer.ForAdvice()
.include(JettyHandlerAdvice.class.getClassLoader())
.advice(named("addFilterWithMapping").and(ElementMatchers.takesArgument(0,named("org.eclipse.jetty.servlet.FilterHolder"))),JettyHandlerAdvice.class.getName())
)
Advice
#Advice.OnMethodEnter
private static void before(#Advice.AllArguments Object[] args, #Advice.Origin("#m") String methodName, #Advice.This Object thiz) {
FilterHolder filterHolder = ((org.eclipse.jetty.servlet.ServletHandler)thiz).addFilterWithMapping(XYZFilter.class, "/*", EnumSet.of(javax.servlet.DispatcherType.REQUEST));
}
Byte Buddy is a code generation framework and is not aspect-oriented. Think of the code being copy-pasted to the target location; the stack overflow error you are seing would be the same if you hardcoded the instrumentation into your target method.
This can be avoided by adding a flag, for example, you could define a ThreadLocal<Boolean> that you set to true before making a recursive call, for example:
if (!threadLocal.get()) {
threadLocal.set(true);
try {
// your code here.
} finally {
threadLocal.set(false);
}
}
This way, you can keep track of a recursive call. You do however need to manage your state somehome. One option would be to inject a holder class for your property into the bootstrap class loader using the Instrumentation interface.
Alternatively, you can check the stack for a recurive call. This is not as efficient as the explicit state management but starting with Java 9, you can use the stack walker API which is much cheaper and makes this approachable.

Clean code , testing and re-usability clarification

Aiming for clean code and testing . Each function / method , should do one and only one thing. this is the theory. to illustrate that i want to share with you some code and then question.
Let's say we need a method that will return a list of players if a condition is true and an empty list of the condition is false.
First approach: One method:
public List<int> ListOfPlayersIDs(int InputNumber)
{
if (Condition)
{
return new List<int>(new int[] {1, 2, 3}); // return a list with items
}
else
{
return new List<int>();//return an empty list
}
}
So here the method ListOfPlayersIDs performs two things:
returns a list of players
Verify if a condition is valid and returns an empty list if not
To divide those "functionality" we can have one method to check the condition and one to return the list of players.
Something like this:
Second approach: Two methods:
First Method
public bool ArePlayerValidForThisNumber(int InputNumber)
{
If (condition)
return true;
else return false;
//Or simply return condition;
}
Second method
public List<int> ListOfPlayersIDs(int InputNumber)
{
return new List<int>(new int[] {1, 2, 3}); // return a list with items
}
My question is :
Which approach do you follow and apply in your coding.
For me the second one is testable, reusable and each method does exactly what it suppose to do. but isn't just a theory in books? I read a lot of code and it does not respect this pattern.
What's your take on this?
It depends (tm). And it depends if you make your code cleaner and easier to understand when you break things into smaller methods.
Personally I would keep the external interface the same (the method can return a filled list or empty), as otherwise, if your client needs to do code if/else clause, you might be leaking logic. Also, I would use an approach called 'code at two levels of abstraction' or 'each method should descend one level of abstraction'. By doing this the final code might look like
public List<int> ListOfPlayersIDs(int InputNumber)
{
if (methodDescribingTheBusinessCondition()) {
return methodDescribingPositiveOutcome();
} else {
return methodNameDescribingNegativeOutcome();
}
}
The idea is that all of this should read like "normal" English, so someone reading the code will get the idea of what's going on without having to know all the nitty gritty details. Here each method is also doing just one thing and the method that orchestrates the whole thing is usually called a "policy" (as it describes your functionality).
If your method is simple, this level of abstraction might make it more difficult to understand.
Last but not least, this approach is explained in a few books (Clean Code to be very specific), and it's used as a good practice in professional development.

When to 'return' in an Objective-C method

Just a quick question. I was just wandering whether or not, I still have to "return;" even in a void function?
At the moment, even in methods which are not returning a variable/etc... I still have "return" at the end of the method.
So do I still need this? Because I swear without it, it does NOT return to where it was called from.
EG:
-(void)viewDidLoad {
[super viewDidLoad];
// Run other setup code....
// Run method 1.
[self method_01];
// Run next bit of code....
}
-(void)method_01 {
// Run code....
return;
}
Do I still have to do it like the above example?
Thanks for your time, Dan.
If the return is at the end of the method, it doesn't make any difference.
-(void) doSomethingWithX:(int) X
{
..........................
........some Code.........
..........................
return ;
}
The control would reach the caller one the method execution completes. Marking a return does the same.
However in a condition like below,
-(void) doSomethingWithX:(int) X
{
if(X>10)
{
return;
}
..........................
........some Code.........
..........................
}
The some code will not be executed if your X value is greater than 10. So, by default control return to the caller at the end of method. Use return if you want to force a return to caller in between the method execution.
You do not. The method will return to its previous point of execution once it reaches the end of the current scope.
You do not need to call return in methods that are defined with void and thus do not return a value.
There are times when you would want to call return in such methods, such as if you want to exit out of the method without executing the remaining code, if a particular condition is met:
if (iHaveDeterminedIAmFinished) {
return;
}
... // code that would otherwise execute.
Other than this, it would be bad practice to routinely include return at the end of every method. Every Objective-C method returns without exception, if it reaches the end of the method without a previous return. Therefore, this practice would not be more clear to a reader who has any familiarity with Objective-C. Indeed, it would likely confuse other developers reading your code who would be left wondering what the intention was. It would be likely to appear like something had been omitted from the end of the method, since there would be no reason for including this return otherwise. In short, I suggest it would be bad practice to include unnecessary return calls at the end of methods.
Because I swear without it, it does NOT return to where it was called from.
Something else is going on here. You may well need to figure out what it is, but it is not correct that the absence of return calls would prevent a return to the point of execution. Either it is returning, and you're not realising it for some reason, or something else is happening in your code.
You can do it either way. It should return automatically without an explicit return.