Clean code , testing and re-usability clarification - testing

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.

Related

refactor if to takeIf and return "return" without label kotlin

I am trying to write more idiomatic Kotlin code and I am stuck with the best way to refactor this if condition. Basically when the condition if true (fragment is GenericActionsBottomSheetDialog instance in a list of Fragments) I return the funcion itself.
Here is what I had and how I refactored it. Is there better way to achieve it? After my refactoring it get worse:
Before refactor:
supportFragmentManager.fragments.iterator().forEach {
if (it is GenericActionsBottomSheetDialog)
return
After refactor:
supportFragmentManager.fragments.iterator().forEach { it ->
it.apply {
takeIf { it is GenericActionsBottomSheetDialog }?.apply { return }}}
If this forEach is the only thing in your current function (which it should IMO), you could get rid of the non-local return by using takeWhile instead:
supportFragmentManager.fragments
.takeWhile { it !is GenericActionsBottomSheetDialog }
.forEach {
// do stuff
}
/!\ be careful that this changes semantics if there is other stuff after the forEach in the same function declared with fun.
If you expect many fragments in the list, you could also use asSequence() before takeWhile so you don't create an intermediate list.
Here's one possibility, which separates the decision from the action:
if (supportFragmentManager.fragments.any{ it is GenericActionsBottomSheetDialog })
return
I think this approach makes the intent clearest. (It's also about the most efficient.)
any() simply checks each item in turn, stopping when it finds a match (or when it reaches the end of the list). Kotlin has many functions like this (inspired by functional programming languages) that use lambdas to operate on lists and other structures. They tend to be named for what they do, rather than how they do it — which makes code using them both short and easy to read. (You should be writing code for people to read, as much as for computers to execute!)
For completeness, here's another approach, which uses filterIsInstance():
if (supportFragmentManager.fragments
.filterIsInstance<GenericActionsBottomSheetDialog>)
.isNotEmpty())
return
There are bound to be many other ways. But I agree with the commenter that your ‘refactored’ approach, while using many more Kotlin functions, has little else to recommend it!
This is an opinion based question, and answers cannot be any different.
That being said: there is nothing wrong with if clauses. From what I can see from your current question, I'd leave it with an if.
Now, if you really do not want to use it, filter elements that are not of type GenericActionsBottomSheetDialog and apply whatever function you want on them (the part that is in your else clause, which we do not see).
EDIT:
In case you only want to check if the object of the GenericActionsBottomSheetDialog exists in the collection, you can perhaps do it like this:
val dialogExists = supportFragmentManager.fragments
.firstOrNull { it is GenericActionsBottomSheetDialog} != null
if (dialogExists) {
return
}
#gidds solution is IMO the most idiomatic one:
if (supportFragmentManager.fragments
.any { it is GenericActionsBottomSheetDialog }) return
I would like to add this solution eliminating the if:
supportFragmentManager.fragments
.firstOrNull { it is GenericActionsBottomSheetDialog }
?.run { return }
It's a matter of taste which one you pick, I prefer the first one.
I was wondering why you use the iterator? You could simply do:
supportFragmentManager.fragments.forEach {

Iterate through a set and print only one message instead of one for each item on set

I'm trying to iterate through a set to find an item. If the item is found, I want it to print a certain message and another message if item is not found. So far, it works but it print a message for each item on the set, whereas I only want one message to display: either if the item was found with the price or the message that it wasn't found. I understand this is happening because of the for loop but I'm not sure how to get it to display the not found message only once and iterate through the set all the same.
This is the code:
fun getArticleOut(code:String) {
fun onSuccess(price: Int): String {
return "Price is $price"
}
fun onError(): String {
return "Article not found"
}
for (i in house.articles) {
if (i.code.equals(code)) {
val price = calculatePrice(
articleType = i.articleType,
totalTime = i.totalTime.toInt(),
hasCard = !i.hasCard.isNullOrEmpty()
)
println(onSuccess(price))
house.articles.remove(i)
} else {
println(onError())
}
}
}
Just to clarify:
data class House(val articles: MutableSet<Articles>)
data class Articles(val code: String,
var articleType: ArticleType,
var totalTime: Calendar,
var hasCard:String?=" ")
The direct answer is the break statement, which breaks out of a for or while loop.  You'd then have to move the onError() call outside the loop, with some way of telling whether the loop completed or not.  For example:
var found = false
for (i in house.articles) {
if (i.code == code) {
val price = calculatePrice(
articleType = i.articleType,
totalTime = i.totalTime.toInt(),
hasCard = !i.hasCard.isNullOrEmpty())
println(onSuccess(price))
house.articles.remove(i)
found = true
break
}
}
if (!found)
println(onError())
If you don't need to do anything after both cases (as in the code in question), then you could simplify it to return, and avoid the flag:
for (i in house.articles) {
if (i.code == code) {
val price = calculatePrice(
articleType = i.articleType,
totalTime = i.totalTime.toInt(),
hasCard = !i.hasCard.isNullOrEmpty())
println(onSuccess(price))
house.articles.remove(i)
return
}
}
println(onError())
However, there are probably better approaches that don't need manual iteration.  Kotlin's standard library is so powerful that any time you find yourself writing a loop, you should stop and ask whether there's a library function that would make it simpler.
In particular, you could use find(), e.g.:
val article = house.articles.find{ it.code == code }
if (article != null) {
val price = calculatePrice(
articleType = article.articleType,
totalTime = article.totalTime.toInt(),
hasCard = !article.hasCard.isNullOrEmpty())
println(onSuccess(price))
house.articles.remove(article)
} else {
println(onError())
}
That makes the code easier to read, too.  (Note that the code is now saying what it's doing, not how it's doing it, which is usually an improvement.)
There are also deeper design questions worth asking, which could lead to further simplifications.  For example:
If code is a unique identifier for Article, another option would be to make articles a Map from code to the corresponding Article; both checking and removal would then be constant-time operations, so more efficient as well as more concise.  (Of course, that depends on how often you're doing these lookups, and what else is setting or using articles.)
Or you could override Article.equals() to check only the code.  Then you could create a dummy Article with the code you're looking for, and do a simple in test (which uses the set's contains method) to check for its presence.  Accessing and removing the ‘true’ one in the set would be harder, though, so that may not be a good fit.
Would be neater for calculatePrice() to be defined to take an Article directly?  (Obviously that depends on whether it could be calculating the price of anything else too.)  Could it even be a method or extension function on Article?  (That probably depends whether the price is conceptually a property of the article itself, or whether it's specific to the getArticleOut() function and any surrounding code.)
Also worth pointing out that the code in the question has a nasty bug (which all these changes also work around), which is that it's trying to modify a collection while iterating through it, which is dangerous!
If you're lucky, you'll get an immediate ConcurrentModificationException showing you exactly what went wrong; if you're less lucky it'll continue but do something unexpected, such as skipping over an element or giving an apparently-unrelated error later on…
Which is another reason to avoid manual iteration where possible.
(The only safe way to remove an element while iterating is to manage the Iterator yourself, and use that to do the removal.)

How to repeat Mono while not empty

I have a method which returns like this!
Mono<Integer> getNumberFromSomewhere();
I need to keep calling this until it has no more items to emit. That is I need to make this as Flux<Integer>.
One option is to add repeat. the point is - I want to stop when the above method emits the first empty signal.
Is there any way to do this? I am looking for a clean way.
A built-in operator that does that (although it is intended for "deeper" nesting) is expand.
expand naturally stops expansion when the returned Publisher completes empty.
You could apply it to your use-case like this:
//this changes each time one subscribes to it
Mono<Integer> monoWithUnderlyingState;
Flux<Integer> repeated = monoWithUnderlyingState
.expand(i -> monoWithUnderlyingState);
I'm not aware of a built-in operator which would do the job straightaway. However, it can be done using a wrapper class and a mix of operators:
Flux<Integer> repeatUntilEmpty() {
return getNumberFromSomewhere()
.map(ResultWrapper::new)
.defaultIfEmpty(ResultWrapper.EMPTY)
.repeat()
.takeWhile(ResultWrapper::isNotEmpty)
}
// helper class, not necessarily needs to be Java record
record ResultWrapper(Integer value) {
public static final ResultWrapper EMPTY = new ResultWrapper(null);
public boolean isNotEmpty() {
return value != null;
}
}

Optimizing a method with boolean flag

I have a method whose purpose is to retrieve collection items.
A collection can contain a mix of items, let's say: pens, pencils, and papers.
The 1st parameter allows me to tell the method to retrieve only the itemTypes I pass (e.g, just pens and pencils).
The 2nd parameter flags the function to use the collection's default item types, instead.
getCollectionItems($itemTypes,$useCollectionDefaultItemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
if($useCollectionDefaultItemTypes) {
// get collection's items using collection->itemTypes
}
else {
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
}
What feels odd is that if I set the $useCollectionDefaultItemTypes to true, there is no need for the function to use the first parameter. I was considering refactoring this method into two such as:
getCollectionItems($itemTypes); // get the items using $itemTypes
getCollectionItems(); // get the items using default settings
The problem is that the methods will have lots of duplicate code except for the if-statement area.
Is there a better way to optimize this?
Pass in $itemTypes as null when you're not using it. Have your if statement check if $itemTypes === null; if it is, use default settings.
If this is php, which I assume it is, you can make your method signature function getCollectionItems($itemTypes = null) and then you can call getCollectionItems() and it will call it as if you had typed getCollectionItems(null).
It's generally a bad idea to write methods that use flags like that. I've seen that written in several places (here at #16, Uncle Bob here and elsewhere). It makes the method hard to understand, read, and refactor.
An alternative design would be to use closures. Your code could look something like this:
$specificWayOfProcessing = function($a) {
//do something with each $a
};
getCollectionItems($processer) {
foreach() {
foreach() {
foreach() {
// lots of code...
$processor(...)
// lots of code...
}
}
}
}
getCollectionItems($specificWayOfProcessing);
This design is better because
It's more flexible. What happens when you need to decide between three different things?
You can now test the code inside the loop much easier
It is now easier to read, because the last line tells you that you are "getting collection items using a specific way of processing" - it reads like an English sentence.
Yes, there is a better way of doing this -- though this question is not an optimization question, but a style question. (Duplicated code has little effect on performance!)
The simplest way to implement this along the lines of your original idea is to make the no-argument form of getCollectionItems() define the default arguments, and then call the version of it that requires an argument:
getCollectionItems($itemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
getCollectionItems() {
getCollectionItems(collection->itemTypes)
}
Depending on what language you are using, you may even be able to collapse these into a single function definition with a default argument:
getCollectionItems($itemTypes = collection->itemTypes) {
foreach() {
foreach() {
foreach() {
// lots of code...
// get collection's items using $itemTypes
}
// lots of code...
}
}
}
That has the advantage of clearly expressing your original idea, which is that you use $itemTypes if provided, and collection->itemTypes if not.
(This does, of course, assume that you're talking about a single "collection", rather than having one of those foreach iterations be iterating over collections. If you are, the idea to use a null value is a good one.)

Chaining continuations together using .NET Reactive

Newbie Rx question. I want to write a method like the following:
public IObsevable<Unit> Save(object obj)
{
var saveFunc = Observable.FromAsyncPattern(...);
saveFunc(obj).Subscribe(result =>
{
Process(result);
return Observable.Return(new Unit());
});
}
The basic idea is: Save the given object, process the results in my "inner" continuation, then allow the caller's "outer" continuation to execute. In other words, I want to chain two continuations together so that the second one does not execute until the first one finishes.
Unfortunately, the code above does not compile because the inner continuation has to return void rather than an IObservable. Plus, of course, returning an observable Unit out of a lambda is not the same as returning it from the containing function, which is what I really need to do. How can I rewrite this code so that it returns the observable Unit correctly? Thanks.
Simplest solution is to use SelectMany
public IObsevable<Unit> Save(object obj)
{
var saveFunc = Observable.FromAsyncPattern(...);
return saveFunc(obj).SelectMany(result =>
{
Process(result);
return Observable.Return(new Unit());
});
}