Pourquoi et comment utiliser les énumérations à la place des booléens

Cet article est libre d'accès pour tous grâce à la générosité des abonnés de Mindsers Blog qui soutiennent notre blog indépendant. Si vous appréciez le contenu que je propose, je vous invite à vous abonner dès aujourd'hui.

Cet article est inspiré de celui d’Andrew Bancroft. Pour les anglophones, n’hésitez pas à le lire, c’est très bien écrit et expliqué.

L’idée n’est pas de remettre en cause l’utilisation des booléens ou leur existence, mais plutôt de réfléchir aux cas où il serait peut-être mieux de préférer les énumérations aux booléens.

Bien sûr, le choix entre booléen et énumération fait partie des habitudes de programmation de chacun et les deux méthodes fonctionnent. Par contre, je vais vous expliquez pourquoi moi (après lecture de l’article d’Andrew), j’ai décidé de réserver les booléens à certain cas d’utilisation précis et les énumérations à d’autres.

En règle générale, je réserve les booléens au code interne de mon objet et les énumérations pour transposer simplement les informations lors des interactions avec cet objet. Le but étant de rendre le code toujours plus lisible et plus simple pour améliorer l’expérience de développement et de maintenance.

Le cas étudié

Pour vous faire comprendre simplement dans quel genre de cas il est bien d’utiliser l’énumération prenons un exemple.

Un webzine souhaite proposer à ses lecteurs une offre premium leur permettant d’accéder à des articles inédits et plus recherchés que les versions gratuites. Au moment de montrer aux lecteurs le contenu on souhaite donc tester si le lecteur a souscrit à l’offre premium ou pas. À première vue les booléens s’adapteraient bien à la situation, mais si on veut savoir :

  1. Si en effet il a souscrit à l’offre ou pas, afin de lui montrer son contenu ?
  2. S’il a souscrit, mais son abonnement a expiré, afin de l’avertir et lui demander de renouveler son accès ?
  3. S’il n’a jamais souscrit à l’offre, afin de lui proposer une offre de bienvenue ?

Si l’on reste sur l’idée des booléens, on se retrouve après réflexion avec plusieurs méthodes dans notre objet Reader qui servent à la même chose — indiquer l’état d’abonné du lecteur en nous renvoyant un booléen — et il faudra faire plusieurs tests dans notre code métier pour comprendre pleinement la situation de l’utilisateur :

  • isSubscriber
  • isSubscriptionExpired
  • isNonSubscriber

Pourquoi les énumérations ?

Vous avez sûrement déjà compris où est ce que je veux en venir. Dans notre cas l’utilisation des booléens est un peu lourde et le code ne sera pas très lisible pour le pauvre développeur qui utilisera notre classe.

public enum SubscriberStatus { 
  case CurrentSubscriber 
  case ExpiredSubscriber 
  case NonSubscriber
}

Si par contre nous n’avons qu’une seule méthode dans notre objet Reader qui renvoie l’état de l’abonnement par l’intermédiaire de l’énumération ci-dessus ?

Cette méthode se présenterait comme suit :

func status() -> SubscriberStatus { 
    if true { 
        return .CurrentSubscriber 
    } 

    if true { 
       return .ExpiredSubscriber 
    } 

    return .NonSubscriber 
}

Les true ne sont là que pour l’exemple même si, me direz-vous, lorsque l’on utilise une structure conditionnelle – Quel que soit le code métier – on utilise des booléens.

Je suis d’accord. Mais comme il est précisé plus haut dans l’article, dans beaucoup de cas nous utiliserons toujours les booléens dans notre code métier, mais nous cherchons ici à clarifier et rendre plus lisible les interactions avec notre objet.

Je vous mets aussi la version d’Andrew qui est plus logique et utilise mieux les subtilités de Swift : subscriberStatus (ou status pour nous) est pour lui un attribut de Reader, il utilise donc un attribut en lecture seule qui calcule sa valeur à la volée lorsqu’on la demande.

public struct Reader {
    public var subscriberStatus: SubscriberStatus {
		get {
			if (noSubscriptionOnFile()) {
				return .NonSubscriber
			}
			if (subscriptionOverdueForPayment()) {
				return .ExpiredSubscriber
			}
			return .CurrentSubscriber
		}
	}
	private func noSubscriptionOnFile() - > Bool {
		// Do what needs to be done to check if the registrant has a subscription on file or not
	}
	private func subscriptionOverdueForPayment() - > Bool {
		// Do what needs to be done to check if the registrant's subscription is overdue for payment
	}
}

Join 100+ developers and entrepreneurs and get notified on every new content.

No spam ever. Unsubscribe in a single click at any time.

Si vous avez des questions ou des remarques/conseils, n'hésitez pas à laisser un commentaire plus bas ! Je serais ravis de vous lire. Et si vous aimez l'article, n'oubliez pas de le partager avec vos amis.