Best practice for writing lots of similar functions/processes - node.js

I have some language agnostic and design pattern related question although I am programming in javascript/node.js if it matters.
It is actually very simple and maybe trivial for some experienced programmers.
Lets say we have a function/method that does some process (call it business logic) by calling other functions which are dealing with specific sub-problems.
function doProcess(){
subProcessA();
subProcessB();
subProcessC();
return "OK"
}
But then, we get task to do similar process but this new process must not call subProcessA.
So for example we have next part of code:
function doProcess2(){
subProcessB();
subProcessC();
return "OK"
}
So my question is how to design code or should I:
A) Make every time new function for new process like in upper example but then I have lots of redundant code and repeating myself every time.
B) Do big IF in process code like this one:
if(some-condition){
subProcessA()
}
But then my code will look very bad.
C) Migrate that IF directly in subprocessA :
if(!some-condition){
return // do nothing
}
but again it looks like coupled code and also I have a feeling that it is not best approach.
D) Something else?

It all boils down to the point where it matters how frequently you call a subFunctionN() for performing that sub-task. Now if you have a linear dependency wherein you need to call a sub-function right before another sub-function, and if this coupling is more predominant in your code than this coupling should be made a part of a separate sub-function which performs more than just one sub-task.
for e.g:
Function MasterFunctionA(){
subFunctionCouplet_12();
subFunction3();
}
Function MasterFunctionB(){
subFunction1();
subFunction3();
}
Function subFunctionCouplet_12(){
subFunction1();
subFunction2();
}
Function subFunction1(){
//do something here...
}
Function subFunction2(){
// do something here...
}
Function subFunction3(){
// do something here...
}
Though this is just an example of how to modularize your code for not repeating yourself, the actual implementation for your code will be purely based on your liking of modularization. The basic guidelines to follow here are that you do not repeat the actual business logic in more than one function, but the encapsulating function can be repeated any number of times throughout your code, given that you can keep the repetition to a minimum.

Related

Is there a (pattern?) name to various concurrent computation?

I am looking for the name and info on a pattern (?) that I'm contemplating. As I don't know the name, it's difficult to search for it.
Here's what I'm trying to do, with a totally hypothetical example...
find-flight ( trip-details, 'cheapest') :: flight
I have this public function, find-flight(...), that accepts 2 parameters, trip-details and some instruction to apply. It returns a single flight, not a list of them.
When I call it with 'cheapest', the function will wait for all available flight results to come in from expedia, travelocity, hotwire, etc, to assure the cheapest flight is found.
When I call it with 'shortest-flight', the function would do the same kind of underlying work as 'cheapest' but would return the shortest flight. I'm sure you can come up with other instructions to apply.
BUT! I'm specifically interested in a variant of this: the instruction (implied or not) would be 'I-am-filthy-rich-and-I-want-to-buy-a-ticket-now'. In other words, the function would call all the sources such as expedia, orbitz, etc, but would return the very first internally received result, at any price point.
I'm asking because I want my public function to be as quick as possible. I can think of a number of strategies that would make it respond fast, but I'm not sure that I know which approach would be best considering that the parameter is unknown until called, right?
So I'm thinking about writing various versions of this function that would all be called by the public version. It'd return the first result. Then, the other strategies could optionally be aborted. If I did that, I could get some metrics on the function and further optimize.
If I were to write this in Java, I'd have a bunch of future objects that the function would loop through to see which one is done first. I'd return that one.
What's that called?
It's been proposed that the pattern is called Promise Race

Best Approach to Callbacks for Asynchronous Function Calls in a Conditional

I would like to know what do you believe is the more elegant way to handle common code executed after a conditional synchronous function call.
For example, assume that there is a function that handles "identify and sort shapes from smallest to largest". Depending on the condition result (e.g. "is the shape to be searched for a triangle or a circle?"), one of two different asynchronous functions can be executed (assume in my example that for some reason the logic can't be combined into a single function):
Find all shapes that are a triangle
Find all shapes that are a circle
Based on the outcome of one of the two functions (depending on the condition), the subsequent section of code would have to be executed. That logic (call it "sort shapes") is assumed the same regardless whether the shape being searched for is a triangle or a circle.
If I used callbacks, I would separate the code after the calls to 1 and 2 above, into a separate dedicated "sort shapes" function that would be the same callback, like this:
function identifyAndSortShapes() {
if (searchingForShape === TRIANGLE)
findTriangleShapes(sortShapes) // sortShapes is the common callback
else
findCircleShapes(sortShapes)
... // The common code that would have been here is then moved to a
... // separate (callback) function sortShapes, due to the asynchronous
... // functions sharing the same callback logic
}
function findTriangleShapes(callback) {
... // Some asynchronous operation, e.g. DB query
callback()
}
function findCircleShapes(callback) {
... // Some asynchronous operation, e.g. DB query
callback()
}
function sortShapes() {
...
}
But is this practice (separating the code that I would have left within the identifyAndSortShapes function, into a separate sortShapes callback function) the right way to go? Or is there a more elegant way to handle this conditional asynchronous function call and then have the same callback code for both without having to create a separate function?
Apologies as my abstraction example might not be the best choice, but I think it shows what my current issue is. I believe this might be a basic conceptual one (on how to properly structure asynchronous code), so I look forward to your advice that could help me shine some light on this.

What's the convention for when you offer an async variant of the same code?

Let foo be sub or method. I have programmed a blocking and an async variant, so looking from the outside the essential difference is in the return value. I first thought of specifying it in the signature, but the dispatcher unfortunately only looks at the incoming end instead of both:
> multi sub foo (--> Promise) {}; multi sub foo (--> Cool) {};
> my Promise $p = foo
Ambiguous call to 'foo(...)'; these signatures all match:
:( --> Promise)
:( --> Cool)
in block <unit> at <unknown file> line 1
Should I add a Bool :$async to the signature? Should I add a name suffix (i.e. foo and foo-async) like in JS? Both don't feel much perlish to me. What are the solutions currently in use for this problem?
Multiple dispatch on return type cannot work, since the return value itself could be used as the argument to a multiple dispatch call (and since nearly every operator in Perl 6 is a multiple dispatch call, this would be a very common occurrence).
As to the question at hand: considering code in core, modules, and a bunch of my own code, it seems that a given class or module will typically offer a synchronous interface or an asynchronous interface, whichever feels most natural for the problem at hand. In cases where both make sense, they are often differentiated at type or module level. For example:
Core: there are both Proc and Proc::Async, and IO::Socket::INET and IO::Socket::Async. While it's sometimes the case that a reasonable asynchronous API can be obtained by providing Promise-returning alternatives for each synchronous routine, in other cases the overall workflow will be a bit different. For example, for a synchronous socket API it's quite reasonable to sit in a loop asking for data, whereas the asynchronous API is much more naturally expressed in Perl 6 by providing a Supply of the packets arriving over the network.
Libraries: Cro::HTTP::Client offers a consistently asynchronous interface to doing HTTP requests. There is no synchronous API.
Applications: considering a lot of my application code, things seem to be either consistently synchronous or consistently asynchronous in terms of their API. The only exceptions I'm finding are classes that are almost entirely synchronous, except they have a few Supply-returning methods in order to provide notifications of events. This isn't really the case being asked about, however, since notifications are naturally asynchronous.
It's interesting that we've ended up here, in contrast to in various other languages where providing async variants through a naming convention is common. I think much of the reason is that one can use await anywhere in Perl 6. This is not the case in languages that have an async/await pair, where in order to use await one must first refactor the calling routine to be async, and then refactor its callers to be async, etc.
So if we are writing a completely synchronous bit of code and want to use something from a module that returns a Promise, our entire cost is "just write await". That's it. Writing in a call to await is the same length as a -sync or -async suffix, or a :sync or :async named argument.
On the other hand, one might choose to provide a synchronous API to something, even if on the inside it is doing an await, because the feeling is most consumers will just want to use it synchronously. Should someone wish to call it asynchronously, there's another 5-letter word, start, that will trigger it on the threadpool, and any await that is performed inside of the code will not (assuming Perl 6.d) block up a real thread, but instead just schedule it to continue when the awaited work is done. That's, again, the same length - or shorter - than writing an async suffix, named argument, etc.
Which means the pattern we seem to be ending up with (given the usual caveats about young languages, and conventions taking time to evolve) is:
For the simple case: pick the most common use case and provide that, letting the caller adapt it with start (sync -> async) or await/react (async -> sync) if they want the other thing
For more complex cases where the sync and async workflows for using the functionality might look quite different, and are both valuable: provide them separately. Granted, one may be a facade of the other (for example, Proc in core is actually just a synchronous adaptation layer over Proc::Async).
A final observation I'd make is that individual consumers of a module will almost certainly be using it synchronously or asynchronously, not a mixture of the two. If wishing to provide both, then I'd probably instead look to using export tags, so I can do:
use Some::Thing :async;
say await something();
Or:
use Some::Thing :sync;
say something();
And not have to declare which I want upon each call.

Is it a bad idea to use the new Dynamic Keyword as a replacement switch statement?

I like the new Dynamic keyword and read that it can be used as a replacement visitor pattern.
It makes the code more declarative which I prefer.
Is it a good idea though to replace all instances of switch on 'Type' with a class that implements dynamic dispatch.
class VistorTest
{
public string DynamicVisit(dynamic obj)
{
return Visit(obj);
}
private string Visit(string str)
{
return "a string was called with value " + str;
}
private string Visit(int value)
{
return "an int was called with value " + value;
}
}
It really depends on what you consider a "good idea".
This works, and it works in a fairly elegant manner. It has some advantages and some disadvantages to other approaches.
On the advantage side:
It's concise, and easy to extend
The code is fairly simple
For the disadvantages:
Error checking is potentially more difficult than a classic visitor implementation, since all error checking must be done at runtime. For example, if you pass visitorTest.DynamicVisit(4.2);, you'll get an exception at runtime, but no compile time complaints.
The code may be less obvious, and have a higher maintenance cost.
Personally, I think this is a reasonable approach. The visitor pattern, in a classic implementation, has a fairly high maintenance cost and is often difficult to test cleanly. This potentially makes the cost slightly higher, but makes the implementation much simpler.
With good error checking, I don't have a problem with using dynamic as an approach here. Personally, I'd probably use an approach like this, since the alternatives that perform in a reasonable manner get pretty nasty otherwise.
However, there are a couple of changes I would make here. First, as I mentioned, you really need to include error checking.
Second, I would actually make DynamicVisit take a dynamic directly, which might make it (slightly) more obvious what's happening:
class VistorTest
{
public string DynamicVisit(dynamic obj)
{
try
{
return Visit(obj);
}
catch (RuntimeBinderException e)
{
// Handle the exception here!
Console.WriteLine("Invalid type specified");
}
return string.Empty;
}
// ...Rest of code
The visitor pattern exists primarily to work around the fact that some languages do not allow double dispatch and multiple dispatch.
Multiple dispatch or multimethods is the feature of some object-oriented programming languages in which a function or method can be dynamically dispatched based on the run time (dynamic) type of more than one of its arguments. This is an extension of single dispatch polymorphism where a method call is dynamically dispatched based on the actual derived type of the object. Multiple dispatch generalizes the dynamic dispatching to work with a combination of two or more objects.
Until version 4, C# was one of those languages. With the introduction of the dynamic keyword, however, C# allows developers to opt-in to this dispatch mechanism just as you've shown. I don't see anything wrong with using it in this manner.
You haven't changed the type safety at all, because even a switch (or more likely dispatch dictionary, given that C# does not allow switching on type) would have to have a default case that throws when it can't match a function to call, and this will do exactly the same if it can't find a suitable function to bind to.

Why is the 'if' statement considered evil?

I just came from Simple Design and Testing Conference. In one of the session we were talking about evil keywords in programming languages. Corey Haines, who proposed the subject, was convinced that if statement is absolute evil. His alternative was to create functions with predicates. Can you please explain to me why if is evil.
I understand that you can write very ugly code abusing if. But I don't believe that it's that bad.
The if statement is rarely considered as "evil" as goto or mutable global variables -- and even the latter are actually not universally and absolutely evil. I would suggest taking the claim as a bit hyperbolic.
It also largely depends on your programming language and environment. In languages which support pattern matching, you will have great tools for replacing if at your disposal. But if you're programming a low-level microcontroller in C, replacing ifs with function pointers will be a step in the wrong direction. So, I will mostly consider replacing ifs in OOP programming, because in functional languages, if is not idiomatic anyway, while in purely procedural languages you don't have many other options to begin with.
Nevertheless, conditional clauses sometimes result in code which is harder to manage. This does not only include the if statement, but even more commonly the switch statement, which usually includes more branches than a corresponding if would.
There are cases where it's perfectly reasonable to use an if
When you are writing utility methods, extensions or specific library functions, it's likely that you won't be able to avoid ifs (and you shouldn't). There isn't a better way to code this little function, nor make it more self-documented than it is:
// this is a good "if" use-case
int Min(int a, int b)
{
if (a < b)
return a;
else
return b;
}
// or, if you prefer the ternary operator
int Min(int a, int b)
{
return (a < b) ? a : b;
}
Branching over a "type code" is a code smell
On the other hand, if you encounter code which tests for some sort of a type code, or tests if a variable is of a certain type, then this is most likely a good candidate for refactoring, namely replacing the conditional with polymorphism.
The reason for this is that by allowing your callers to branch on a certain type code, you are creating a possibility to end up with numerous checks scattered all over your code, making extensions and maintenance much more complex. Polymorphism on the other hand allows you to bring this branching decision as closer to the root of your program as possible.
Consider:
// this is called branching on a "type code",
// and screams for refactoring
void RunVehicle(Vehicle vehicle)
{
// how the hell do I even test this?
if (vehicle.Type == CAR)
Drive(vehicle);
else if (vehicle.Type == PLANE)
Fly(vehicle);
else
Sail(vehicle);
}
By placing common but type-specific (i.e. class-specific) functionality into separate classes and exposing it through a virtual method (or an interface), you allow the internal parts of your program to delegate this decision to someone higher in the call hierarchy (potentially at a single place in code), allowing much easier testing (mocking), extensibility and maintenance:
// adding a new vehicle is gonna be a piece of cake
interface IVehicle
{
void Run();
}
// your method now doesn't care about which vehicle
// it got as a parameter
void RunVehicle(IVehicle vehicle)
{
vehicle.Run();
}
And you can now easily test if your RunVehicle method works as it should:
// you can now create test (mock) implementations
// since you're passing it as an interface
var mock = new Mock<IVehicle>();
// run the client method
something.RunVehicle(mock.Object);
// check if Run() was invoked
mock.Verify(m => m.Run(), Times.Once());
Patterns which only differ in their if conditions can be reused
Regarding the argument about replacing if with a "predicate" in your question, Haines probably wanted to mention that sometimes similar patterns exist over your code, which differ only in their conditional expressions. Conditional expressions do emerge in conjunction with ifs, but the whole idea is to extract a repeating pattern into a separate method, leaving the expression as a parameter. This is what LINQ already does, usually resulting in cleaner code compared to an alternative foreach:
Consider these two very similar methods:
// average male age
public double AverageMaleAge(List<Person> people)
{
double sum = 0.0;
int count = 0;
foreach (var person in people)
{
if (person.Gender == Gender.Male)
{
sum += person.Age;
count++;
}
}
return sum / count; // not checking for zero div. for simplicity
}
// average female age
public double AverageFemaleAge(List<Person> people)
{
double sum = 0.0;
int count = 0;
foreach (var person in people)
{
if (person.Gender == Gender.Female) // <-- only the expression
{ // is different
sum += person.Age;
count++;
}
}
return sum / count;
}
This indicates that you can extract the condition into a predicate, leaving you with a single method for these two cases (and many other future cases):
// average age for all people matched by the predicate
public double AverageAge(List<Person> people, Predicate<Person> match)
{
double sum = 0.0;
int count = 0;
foreach (var person in people)
{
if (match(person)) // <-- the decision to match
{ // is now delegated to callers
sum += person.Age;
count++;
}
}
return sum / count;
}
var males = AverageAge(people, p => p.Gender == Gender.Male);
var females = AverageAge(people, p => p.Gender == Gender.Female);
And since LINQ already has a bunch of handy extension methods like this, you actually don't even need to write your own methods:
// replace everything we've written above with these two lines
var males = list.Where(p => p.Gender == Gender.Male).Average(p => p.Age);
var females = list.Where(p => p.Gender == Gender.Female).Average(p => p.Age);
In this last LINQ version the if statement has "disappeared" completely, although:
to be honest the problem wasn't in the if by itself, but in the entire code pattern (simply because it was duplicated), and
the if still actually exists, but it's written inside the LINQ Where extension method, which has been tested and closed for modification. Having less of your own code is always a good thing: less things to test, less things to go wrong, and the code is simpler to follow, analyze and maintain.
Huge runs of nested if/else statements
When you see a function spanning 1000 lines and having dozens of nested if blocks, there is an enormous chance it can be rewritten to
use a better data structure and organize the input data in a more appropriate manner (e.g. a hashtable, which will map one input value to another in a single call),
use a formula, a loop, or sometimes just an existing function which performs the same logic in 10 lines or less (e.g. this notorious example comes to my mind, but the general idea applies to other cases),
use guard clauses to prevent nesting (guard clauses give more confidence into the state of variables throughout the function, because they get rid of exceptional cases as soon as possible),
at least replace with a switch statement where appropriate.
Refactor when you feel it's a code smell, but don't over-engineer
Having said all this, you should not spend sleepless nights over having a couple of conditionals now and there. While these answers can provide some general rules of thumb, the best way to be able to detect constructs which need refactoring is through experience. Over time, some patterns emerge that result in modifying the same clauses over and over again.
There is another sense in which if can be evil: when it comes instead of polymorphism.
E.g.
if (animal.isFrog()) croak(animal)
else if (animal.isDog()) bark(animal)
else if (animal.isLion()) roar(animal)
instead of
animal.emitSound()
But basically if is a perfectly acceptable tool for what it does. It can be abused and misused of course, but it is nowhere near the status of goto.
A good quote from Code Complete:
Code as if whoever maintains your program is a violent psychopath who
knows where you live.
— Anonymous
IOW, keep it simple. If the readability of your application will be enhanced by using a predicate in a particular area, use it. Otherwise, use the 'if' and move on.
I think it depends on what you're doing to be honest.
If you have a simple if..else statement, why use a predicate?
If you can, use a switch for larger if replacements, and then if the option to use a predicate for large operations (where it makes sense, otherwise your code will be a nightmare to maintain), use it.
This guy seems to have been a bit pedantic for my liking. Replacing all if's with Predicates is just crazy talk.
There is the Anti-If campaign which started earlier in the year. The main premise being that many nested if statements often can often be replaced with polymorphism.
I would be interested to see an example of using the Predicate instead. Is this more along the lines of functional programming?
Just like in the bible verse about money, if statements are not evil -- the LOVE of if statements is evil. A program without if statements is a ridiculous idea, and using them as necessary is essential. But a program that has 100 if-else if blocks in a row (which, sadly, I have seen) is definitely evil.
I have to say that I recently have begun to view if statements as a code smell: especially when you find yourself repeating the same condition several times. But there's something you need to understand about code smells: they don't necessarily mean that the code is bad. They just mean that there's a good chance the code is bad.
For instance, comments are listed as a code smell by Martin Fowler, but I wouldn't take anyone seriously who says "comments are evil; don't use them".
Generally though, I prefer to use polymorphism instead of if statements where possible. That just makes for so much less room for error. I tend to find that a lot of the time, using conditionals leads to a lot of tramp arguments as well (because you have to pass the data needed to form the conditional on to the appropriate method).
if is not evil(I also hold that assigning morality to code-writing practices is asinine...).
Mr. Haines is being silly and should be laughed at.
I'll agree with you; he was wrong. You can go too far with things like that, too clever for your own good.
Code created with predicates instead of ifs would be horrendous to maintain and test.
Predicates come from logical/declarative programming languages, like PROLOG. For certain classes of problems, like constraint solving, they are arguably superior to a lot of drawn out step-by-step if-this-do-that-then-do-this crap. Problems that would be long and complex to solve in imperative languages can be done in just a few lines in PROLOG.
There's also the issue of scalable programming (due to the move towards multicore, the web, etc.). If statements and imperative programming in general tend to be in step-by-step order, and not scaleable. Logical declarations and lambda calculus though, describe how a problem can be solved, and what pieces it can be broken down into. As a result, the interpreter/processor executing that code can efficiently break the code into pieces, and distribute it across multiple CPUs/cores/threads/servers.
Definitely not useful everywhere; I'd hate to try writing a device driver with predicates instead of if statements. But yes, I think the main point is probably sound, and worth at least getting familiar with, if not using all the time.
The only problem with a predicates (in terms of replacing if statements) is that you still need to test them:
function void Test(Predicate<int> pr, int num)
{
if (pr(num))
{ /* do something */ }
else
{ /* do something else */ }
}
You could of course use the terniary operator (?:), but that's just an if statement in disguise...
Perhaps with quantum computing it will be a sensible strategy to not use IF statements but to let each leg of the computation proceed and only have the function 'collapse' at termination to a useful result.
Sometimes it's necessary to take an extreme position to make your point. I'm sure this person uses if -- but every time you use an if, it's worth having a little think about whether a different pattern would make the code clearer.
Preferring polymorphism to if is at the core of this. Rather than:
if(animaltype = bird) {
squawk();
} else if(animaltype = dog) {
bark();
}
... use:
animal.makeSound();
But that supposes that you've got an Animal class/interface -- so really what the if is telling you, is that you need to create that interface.
So in the real world, what sort of ifs do we see that lead us to a polymorphism solution?
if(logging) {
log.write("Did something");
}
That's really irritating to see throughout your code. How about, instead, having two (or more) implementations of Logger?
this.logger = new NullLogger(); // logger.log() does nothing
this.logger = new StdOutLogger(); // logger.log() writes to stdout
That leads us to the Strategy Pattern.
Instead of:
if(user.getCreditRisk() > 50) {
decision = thoroughCreditCheck();
} else if(user.getCreditRisk() > 20) {
decision = mediumCreditCheck();
} else {
decision = cursoryCreditCheck();
}
... you could have ...
decision = getCreditCheckStrategy(user.getCreditRisk()).decide();
Of course getCreditCheckStrategy() might contain an if -- and that might well be appropriate. You've pushed it into a neat place where it belongs.
It probably comes down to a desire to keep code cyclomatic complexity down, and to reduce the number of branch points in a function. If a function is simple to decompose into a number of smaller functions, each of which can be tested, you can reduce the complexity and make code more easily testable.
IMO:
I suspect he was trying to provoke a debate and make people think about the misuse of 'if'. No one would seriously suggest such a fundamental construction of programming syntax was to be completely avoided would they?
Good that in ruby we have unless ;)
But seriously probably if is the next goto, that even if most of the people think it is evil in some cases is simplifying/speeding up the things (and in some cases like low level highly optimized code it's a must).
I think If statements are evil, but If expressions are not. What I mean by an if expression in this case can be something like the C# ternary operator (condition ? trueExpression : falseExpression). This is not evil because it is a pure function (in a mathematical sense). It evaluates to a new value, but it has no effects on anything else. Because of this, it works in a substitution model.
Imperative If statements are evil because they force you to create side-effects when you don't need to. For an If statement to be meaningful, you have to produce different "effects" depending on the condition expression. These effects can be things like IO, graphic rendering or database transactions, which change things outside of the program. Or, it could be assignment statements that mutate the state of the existing variables. It is usually better to minimize these effects and separate them from the actual logic. But, because of the If statements, we can freely add these "conditionally executed effects" everywhere in the code. I think that's bad.
If is not evil! Consider ...
int sum(int a, int b) {
return a + b;
}
Boring, eh? Now with an added if ...
int sum(int a, int b) {
if (a == 0 && b == 0) {
return 0;
}
return a + b;
}
... your code creation productivity (measured in LOC) is doubled.
Also code readability has improved much, for now you can see in the blink of an eye what the result is when both argument are zero. You couldn't do that in the code above, could you?
Moreover you supported the testteam for they now can push their code coverage test tools use up more to the limits.
Furthermore the code now is better prepared for future enhancements. Let's guess, for example, the sum should be zero if one of the arguments is zero (don't laugh and don't blame me, silly customer requirements, you know, and the customer is always right).
Because of the if in the first place only a slight code change is needed.
int sum(int a, int b) {
if (a == 0 || b == 0) {
return 0;
}
return a + b;
}
How much more code change would have been needed if you hadn't invented the if right from the start.
Thankfulness will be yours on all sides.
Conclusion: There's never enough if's.
There you go. To.

Resources