Code solution to avoid if else conditions - coding-style

I am wondering if anyone can suggest me a design pattern or best way to code the below problem.
1) I have an array list of books like the below
list.add(new Book(title, author);
list.add(new Book(title1, author1);
and so on....
2) And now I would like to find all the books from the list by author
findByAuthor(String author) {
for(Book book : list){
if(book.getAuthor().equals(author)){
return book;
}
}
}
Like wise I have another method called findByTitle(). But, it would be same code except book.getAuthor() will have to be book.getTitle(). Everything will be same.
3) Now i can write a method which is generic to both methods like below;
findByBookProperty (String type, String propertyValue){
for(Book book : list)
if(type.equals("author") && book.getTitle().equals(propertyValue)){
return book;
} //another else if for author
//another else for another property
// if else repeats for all the required finder types...
}
}
4) The problem i have here is;
1. I dont want to use the nasty if/else condition for the finder types.
2. I want to know if there is any design pattern or better way to handle this if else or swich method.
Important note: I get the author name as a request parameter value in my spring controller method.
I appreciate your thoughts.

Use Commons-Collections' Predicates framework:
1) Construct a Predicate instance for each type of test.
2) Use CollectionUtils.select(), passing in the predicate you'd like to use for evaluating objects.
Another alternative is to use Commons-Collections' Transformation framework:
1) Write a Transformer for each type of property you'd like extracted/compared against.
2) Write a generic loop, accepting a Transformer instance as a parameter.

Related

Spring Data + QueryDSL empty predicate + Predicate chaining

let me get straight to the point.
I am using Spring Data JPA with QueryDSL in a project and I cannot figure out this myself.
I have the QueryDSL predicates in static methods that can take arguments and if the argument is not correct it should return "empty predicate" :
public static BooleanExpression byWhateverId(Long whateverId) {
if(whateverId == null) return [insert magic here];
// if parameter is OK return usual predicate
return QClass.property.whateverId.eq(whateverId);
}
Now I want to be able to chain these predicates using AND/OR oprators :
someRepository.findAll(byWhateverId(someParam).and(bySomethingElseId(1));
The problem here is that at this point I don't know whether 'someParam' is null or not (of course I can check but that's a lot of IFs).
I also know I can use BooleanBuilder class but that seems also like a lot of code that should not be needed.
Does anybody knows what could be inserted instead of "[insert magic here]" ???
Or maybe I am missing something somewhere...
Thanks!
You can return null for non matching predicates in byWhateverId and bySomethingElseId and combine the predicate via ExpressionUtils.allOf()
In your case
Predicate where = ExpressionUtils.allOf(byWhateverId(someParam), bySomethingElseId(1));
someRepository.findAll(where);
4 years old question, but anyway...
You can return sql predicate which is always true, like true=true:
public static BooleanExpression alwaysTrue() {
return Expressions.TRUE.isTrue;
}
If you have a bunch of these the generated sql won't be super nice, so you might want to limit such usages to a minimum.
Sorry, I completely forgot about this.
The right solution (from my point of view) is to use BooleanBuilder.

How to match a enum value with some enum values using linq

I want to know what could be the shortest linq query instead of following if statement.
public enum ErrorMessage { Error1=1, Error2=2, Error3=3, Error4=4 }
ErrorMessage error = ErrorMessage.Error4;
if (error == ErrorMessage.Error1 || error == ErrorMessage.Error2)
{
//do something
}
Linq will make this code complicated,
code you provide is readable, fast and maintainable more than Linq will be
You could use
if (new [] {ErrorMessage.Error1, ErrorMessage.Error2}.Contains(error))
{
//do something
}
or
var bad_errors = new [] {ErrorMessage.Error1, ErrorMessage.Error2};
if (bad_errors.Contains(error))
{
//do something
}
if a single call to an extension method is LINQ enough for you.
I guess to most C# developers such a pattern seems strange (and it totally is), but if you're already working on a dynamically created list of errors you want to check against...
Otherwise, stick with if.
It actually works nicer in languages with less boilerplate, e.g. Python, where this pattern is commonly used and looks a lot nicer:
if error in (Error1, Error2):
# do something

How can I intercept the result of an IQueryProvider query (other than single result)

I'm using Entity Framework and I have a custum IQueryProvider. I use the Execute method so that I can modify the result (a POCO) of a query after is has been executed. I want to do the same for collections. The problem is that the Execute method is only called for single result.
As described on MSDN :
The Execute method executes queries that return a single value
(instead of an enumerable sequence of values). Expression trees that
represent queries that return enumerable results are executed when
their associated IQueryable object is enumerated.
Is there another way to accomplish what I want that I missed?
I know I could write a specific method inside a repository or whatever but I want to apply this to all possible queries.
This is true that the actual signature is:
public object Execute(Expression expression)
public TResult Execute<TResult>(Expression expression)
However, that does not mean that the TResult will always be a single element! It is the type expected to be returned from the expression.
Also, note that there are no constraints over the TResult, not even 'class' or 'new()'.
The TResult is a MyObject when your expression is of singular result, like .FirstOrDefault(). However, the TResult can also be a double when you .Avg() over the query, and also it can be IEnumerable<MyObject> when your query is plain .Select.Where.
Proof(*) - I've just set a breakpoint inside my Execute() implementation, and I've inspected it with Watches:
typeof(TResult).FullName "System.Collections.Generic.IEnumerable`1[[xxxxxx,xxxxx]]"
expression.Type.FullName "System.Linq.IQueryable`1[[xxxxxx,xxxxx]]"
I admit that three overloads, one object, one TResult and one IEnumerable<TResult> would probably be more readable. I think they did not place three of them as extensibility point for future interfaces. I can imagine that in future they came up with something more robust than IEnumerable, and then they'd need to add another overload and so on. With simple this interface can process any type.
Oh, see, we now also have IQueryable in addition to IEnumerable, so it would need at least four overloads:)
The Proof is marked with (*) because I have had a small bug/feature in my IQueryProvider's code that has is obscuring the real behavior of LINQ.
LINQ indeed calls the generic Execute only for singular cases. This is a shortcut, an optimization.
For all other cases, it ... doesn't call Execute() it at all
For those all other cases, the LINQ calls .GetEnumerator on your custom IQueryable<> implementation, that what happens is dictated by .. simply what you wrote there. I mean, assuming that you actually provided custom implementations of IQueryable. That would be strange if you did not - that's just about 15 lines in total, nothing compared to the length of custom provider.
In the project where I got the "proof" from, my implementation looks like:
public System.Collections.IEnumerator GetEnumerator()
{
return Provider.Execute<IEnumerable>( this.Expression ).GetEnumerator();
}
public IEnumerator<TOut> GetEnumerator()
{
return Provider.Execute<IEnumerable<TOut>>( this.Expression ).GetEnumerator();
}
of course, one of them would be explicit due to name collision. Please note that to fetch the enumerator, I actually call the Execute with explicitely stated TResult. This is why in my "proof" those types occurred.
I think that you see the "TResult = Single Element" case, because you wrote i.e. something like this:
public IEnumerator<TOut> GetEnumerator()
{
return Provider.Execute<TOut>( this.Expression ).GetEnumerator();
}
Which really renders your Execute implementation without choice, and must return single element. IMHO, this is just a bug in your code. You could have done it like in my example above, or you could simply use the untyped Execute:
public System.Collections.IEnumerator GetEnumerator()
{
return ((IEnumerable)Provider.Execute( this.Expression )).GetEnumerator();
}
public IEnumerator<TOut> GetEnumerator()
{
return ((IEnumerable<TOut>)Provider.Execute( this.Expression )).GetEnumerator();
}
Of course, your implementation of Execute must make sure to return proper IEnumerables for such queries!
Expression trees that represent queries that return enumerable results are executed when their associated IQueryable object is enumerated.
I recommend enumerating your query:
foreach(T t in query)
{
CustomModification(t);
}
Your IQueryProvider must implement CreateQuery<T>. You get to choose the implemenation of the resulting IQueryable. If you want that IQueryable to do something to each row when enumerated, you get to write that implementation.
The final answer is that it's not possible.

Linq to generic list?

in my DAL I have 3-5 Lists of something:
List<User>, List<Items>, List<bla>
Now I want to modify these Lists generic in a method.
How can I write a method with parameters allowed of all of this? (I tried var but don't allowed in the method head)
P.s.: Don't care about type, I will cast it back easily:
List<User> user; user = (List<User>)MethodName(user);
Your question is somewhat vague, but I suspect you're looking for:
void SomeMethod(IList list)
If you're actually changing the list within the method, you don't need a return value.
An alternatively (a nicer one, frankly) is to make the method generic:
void SomeMethod<T>(IList<T> list)

What's so great about Func<> delegate?

Sorry if this is basic but I was trying to pick up on .Net 3.5.
Question: Is there anything great about Func<> and it's 5 overloads? From the looks of it, I can still create a similar delgate on my own say, MyFunc<> with the exact 5 overloads and even more.
eg: public delegate TResult MyFunc<TResult>() and a combo of various overloads...
The thought came up as I was trying to understand Func<> delegates and hit upon the following scenario:
Func<int,int> myDelegate = (y) => IsComposite(10);
This implies a delegate with one parameter of type int and a return type of type int. There are five variations (if you look at the overloads through intellisense). So I am guessing that we can have a delegate with no return type?
So am I justified in saying that Func<> is nothing great and just an example in the .Net framework that we can use and if needed, create custom "func<>" delegates to suit our own needs?
Thanks,
The greatness lies in establishing shared language for better communication.
Instead of defining your own delegate types for the same thing (delegate explosion), use the ones provided by the framework. Anyone reading your code instantly grasps what you are trying to accomplish.. minimizes the time to 'what is this piece of code actually doing?'
So as soon as I see a
Action = some method that just does something and returns no output
Comparison = some method that compares two objects of the same type and returns an int to indicate order
Converter = transforms Obj A into equivalent Obj B
EventHandler = response/handler to an event raised by some object given some input in the form of an event argument
Func = some method that takes some parameters, computes something and returns a result
Predicate = evaluate input object against some criteria and return pass/fail status as bool
I don't have to dig deeper than that unless it is my immediate area of concern. So if you feel the delegate you need fits one of these needs, use them before rolling your own.
Disclaimer: Personally I like this move by the language designers.
Counter-argument : Sometimes defining your delegate may help communicate intent better. e.g. System.Threading.ThreadStart over System.Action. So it’s a judgment call in the end.
The Func family of delegates (and their return-type-less cousins, Action) are not any greater than anything else you'd find in the .NET framework. They're just there for re-use so you don't have to redefine them. They have type parameters to keep things generic. E.g., a Func<T0,bool> is the same as a System.Predicate<T> delegate. They were originally designed for LINQ.
You should be able to just use the built-in Func delegate for any value-returning method that accepts up to 4 arguments instead of defining your own delegate for such a purpose unless you want the name to reflect your intention, which is cool.
Cases where you would absolutely need to define your delegate types include methods that accept more than 4 arguments, methods with out, ref, or params parameters, or recursive method signatures (e.g., delegate Foo Foo(Foo f)).
In addition to Marxidad's correct answer:
It's worth being aware of Func's related family, the Action delegates. Again, these are types overloaded by the number of type parameters, but declared to return void.
If you want to use Func/Action in a .NET 2.0 project but with a simple route to upgrading later on, you can cut and paste the declarations from my version comparison page. If you declare them in the System namespace then you'll be able to upgrade just by removing the declarations later - but then you won't be able to (easily) build the same code in .NET 3.5 without removing the declarations.
Decoupling dependencies and unholy tie-ups is one singular thing that makes it great. Everything else one can debate and claim to be doable in some home-grown way.
I've been refactoring slightly more complex system with an old and heavy lib and got blocked on not being able to break compile time dependency - because of the named delegate lurking on "the other side". All assembly loading and reflection didn't help - compiler would refuse to just cast a delegate() {...} to object and whatever you do to pacify it would fail on the other side.
Delegate type comparison which is structural at compile time turns nominal after that (loading, invoking). That may seem OK while you are thinking in terms of "my darling lib is going to be used forever and by everyone" but it doesn't scale to even slightly more complex systems. Fun<> templates bring a degree of structural equivalence back into the world of nominal typing . That's the aspect you can't achieve by rolling out your own.
Example - converting:
class Session (
public delegate string CleanBody(); // tying you up and you don't see it :-)
public static void Execute(string name, string q, CleanBody body) ...
to:
public static void Execute(string name, string q, Func<string> body)
Allows completely independent code to do reflection invocation like:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Func<string> d = delegate() { .....} // see Ma - no tie-ups :-)
Object [] params = { "foo", "bar", d};
methodInfo.Invoke("Trial Execution :-)", params);
Existing code doesn't notice the difference, new code doesn't get dependence - peace on Earth :-)
One thing I like about delegates is that they let me declare methods within methods like so, this is handy when you want to reuse a piece of code but you only need it within that method. Since the purpose here is to limit the scope as much as possible Func<> comes in handy.
For example:
string FormatName(string pFirstName, string pLastName) {
Func<string, string> MakeFirstUpper = (pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
};
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
It's even easier and more handy when you can use inference, which you can if you create a helper function like so:
Func<T, TReturn> Lambda<T, TReturn>(Func<T, TReturn> pFunc) {
return pFunc;
}
Now I can rewrite my function without the Func<>:
string FormatName(string pFirstName, string pLastName) {
var MakeFirstUpper = Lambda((string pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
});
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
Here's the code to test the method:
Console.WriteLine(FormatName("luis", "perez"));
Though it is an old thread I had to add that func<> and action<> also help us use covariance and contra variance.
http://msdn.microsoft.com/en-us/library/dd465122.aspx

Resources