Faulty factory design and the vague else clause

Note the structure of the if statement in the card() function. We did not use a catch-all else clause to do any processing; we merely raised an exception. The use of a catch-all else clause is subject to debate.

On the one hand, it can be argued that the condition that belongs in an else clause should never be left unstated because it may hide subtle design errors. On the other hand, some else clause conditions are truly obvious.

It's important to avoid a vague else clause.

Consider the following variant on this factory function definition:

def card2(rank: int, suit: Suit) -> Card:
if rank == 1:
return AceCard("A", suit)
elif 2 <= rank < 11:
return Card(str(rank), suit)
else:
name = {11: "J", 12: "Q", 13: "K"}[rank]
return FaceCard(name, suit)

While this kind of code is common, it's not perfectly clear what condition applies to the else: clause. 

The following looks like it might build a valid deck:

deck2 = [card2(rank, suit) for rank in range(13) for suit in iter(Suit)]

This doesn't work. But the error is an obscure KeyError when trying to build a FaceCard instance.

What if the if conditions were more complex? While some programmers will understand this if statement at a glance, others will struggle to determine whether all of the cases are properly exclusive.

We should not force the reader to deduce a complex condition for an else clause. Either the condition should be obvious to the newest of noobz, or it should be explicit.

Catch-all else should be used rarely. Use it only when the condition is obvious. When in doubt, be explicit and use else to raise an exception. Avoid the vague else clause.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset