La Programmation Aphantasique nécessite la création d’une nouvelle façon d’écrire le code informatique.
Le “Kruzik Case” (aussi apellé “K Case” ou “Kcase”) est une convention de nommage de programmation informatique inventée par Marc Kruzik, dont le but est de faciliter la lisibilité et l’évolutivité du code informatique.
- Le Kcase se base sur les sciences cognitives et le refactoring pour établir un nommage naturel.
- Le Kcase réduit le plus possible les variantes d’écriture du code, en préférant toujours la syntaxe la plus lisible et la plus visible.
- Le Kcase place la documentation essentielle au coeur même des noms de variables et de fonctions.
- Le Kcase permet d’économiser sur la représentation mentale en explicitant la parenté des variables et les entrées et sorties des fonctions.
- Le Kcase est une convention de nommage à vocation d’harmonisation universelle, s’adaptant à tous les langages.
Le Kcase est un des fondamentaux de l’Alpha Omega Programming de Marc Kruzik, dont le but est de maximiser l’évolutivité du code informatique en plaçant les choix d’architecture le plus tôt possible.
Séparateur de mots
1- le cerveau humain lit avant tout la première et dernière letre de chaque mot.
On peut le constater avec une phrase dont les lettres sont mélangées.
Exemple de phrase dont les première et de dernières lettres de chaque mot sont conservées, et les lettres intermédiaires sont mélangées :
Bonojur vuos aellz bein
2- Le cerveau humain lit en priorité la moitié supérieure des lettres.
On peut le constater en cachant la moitié supérieure ou inférieure d’une phrase, et en voyant que le texte est plus facile à lire quand on peut voir la moitié supérieure des lettres.
Exemple de phrase avec moitié supérieure :

Exemple de phrase avec moitié inférieure :

Lorsqu’on crée une phrase personnalisée de programmation composée de plusieurs mots (exemple : nom de variable, nom de classe, etc), il est donc plus efficace d’utiliser un séparateur de mots qui permette de bien voir la séparation entre les mots (1) et dégage visuellement la première et la dernière lettre de chaque mot (2).
Il en résulte qu’un caractère s’affichant uniquement dans la moitié inférieure des lettres est naturellement perçu comme un espace.
Exemple de phrase avec séparateur de mot avec lettre majuscule :
BonjourVousAllezBien
Exemple de phrase avec séparateur de mot avec tiret bas :
Bonjour_vous_allez_bien
On utilise donc toujours le caractère “tiret bas” (ou “tiret du 8”) (en anglais, “underscore”) pour séparer les mots.
Nom de classe et variable liée
Les classes commencent par une majuscule, et chaque mot supplémentaire de la classe commence par une majuscule.
Les variables tirées d’une classe commencent par une minuscule, et chaque mot supplémentaire de la variable commence par une majuscule.
class Human
{
}
Human human = new Human ();
class My_Human
{
}
My_Human my_human = new My_Human ();
Référence et sens du nom de variable
Le nom d’une variable doit toujours faire référence à un élément référent s’il existe.
L’élément référent doit toujours être positionné avant le reste du nom de variable.
int human_age = 20;
Ce positionnement permet de faire facilement évoluer le code, pour passer de variables séparées à un objet, en remplaçant le caractère de séparation par un point.
// Avant
int human_age = 20;
// Après
human.age = 20;
Si on a besoin d’être plus précis (en cas de composition complexe), on peut utiliser le mot séparateur “whose”.
int human_whose_age = 20;
A noter que ces différentes déclarations correspondent à la même chose :
// usage simple
int human_age = 20;
// usage pour un objet
human.age = 20;
// usage pour un contexte plus complexe
int human_whose_age = 20;
Variable avec paramètre
Lorsqu’une variable a une caractéristique particulière, on conserve le nom original de la variable, et on ajoute la caractéristique en utilisant le mot séparateur “with”.
Human human = new Human ();
Human human_with_hat = new Human ("hat");
Cas avec paramètres complexes
On préfère limiter les variables et autres éléments à un seul paramètre, que l’on garde simple, avec un seul séparateur “with”. Néanmoins, si plusieurs paramètres de même niveau doivent être spécifiés, on utilise plusieurs séparateurs “with”.
Human human = new Human ();
Human human_with_hat = new Human ("hat");
Human human_with_hat_with_tie = new Human ("hat", "tie");
Variable avec paramètre et référence
On garde toujours le paramètre proche de son élément référent (“at” reste proche de “human”), et on utilise le mot séparateur “whose” ensuite. Exemple où on fait référence à l’âge d’un humain avec un chapeau :
int human_with_hat_whose_age = 20;
Singulier obligatoire et conteneur spécifié
On utilise toujours le singulier dans un nom de variable. Lorsqu’une variable contient plusieurs éléments, on indique en préalable la nature du conteneur de ces éléments.
Man man;
List<man> list_man;
On évite d’utiliser un “s” en fin de nom de variable pour indiquer qu’il y a plusieurs éléments (comme “cats”).
On évite d’utiliser une orthographe plurielle pour un nom de variable (comme “men”).
Conteneurs courants :
- List : list
- Array : arr
- Dictionary : dico
Nom de conteneur dictionnaire
Un dictionnaire est composé de couples “Key, Value” et le nom du dictionnaire doit refléter ces éléments.
Pour faciliter la compréhension des dictionnaires, on utilise le mot séparateur “plus”.
Exemple avec un dictionnaire contenant un nom “name” et un âge “age” :
Dictionary<string, int> dico_name_plus_age;
L’élément « KeyValuePair » de Dictionary suit cette règle.
foreach (KeyValuePair<string, int> kvp_name_plus_age in dico_name_plus_age)
{
string name = kvp_name_plus_age.Key;
int age = kvp_name_plus_age.Value;
}
En cas de composition complexe, le séparateur “plus” a priorité sur la séparation des éléments.
// dico ( (human with hat) plus (age) )
Dictionary<string, int> dico_human_with_hat_plus_age;
Nom des fonctions de conversion
Une fonction de conversion transforme une donnée en une autre.
Elle doit normalement avoir les caractéristiques suivantes :
- De préférence un seul paramètre en entrée
- Etre statique
- Un seul élément en sortie (pas de ref ou out)
public static int from_integer_get_next (int integer)
{
int next = integer + 1;
return next;
}
Variable d’entrée explicite et variable de retour explicite
Pour la fonction suivante :
public static int from_integer_get_next (int integer)
{
int next = integer + 1;
return next;
}
La variable d’entrée (ici « integer ») est présente dans le nom de la fonction :
public static int from_integer_get_next (int integer)
{
int next = integer + 1;
return next;
}
La variable de sortie (ici « next ») est présente dans le nom de la fonction, et elle est créée de façon explicite avant d’être renvoyée :
public static int from_integer_get_next (int integer)
{
int next = integer + 1;
return next;
}
Nom partiel et nom complet
On utilise toujours les noms de variables entiers, avec leur référence.
// good
public static int from_human_get_age (Human human)
{
int age = human.age;
return age;
}
// better
public static int from_human_get_human_age (Human human)
{
int human_age = human.age;
return human_age;
}
// good
public static int from_human_get_dog_age (Human human)
{
int dog_age = human.dog.age;
return dog_age;
}
// better
public static int from_human_get_human_dog_age (Human human)
{
int human_dog_age = human.dog.age;
return human_dog_age;
}
public static int from_human_get_list_dog_age (Human human)
{
List<int> list_dog_age = new List<int> ();
foreach (Dog dog in human.list_dog)
{
list_dog_age.Add (dog.age);
}
return list_dog_age;
}
public static int from_human_with_hat_get_dog_age (
Human human_with_hat)
{
int dog_age = human_with_hat.dog.age;
return dog_age;
}
public static int from_human_and_human_get_age_sum (
Human human_a, Human human_b)
{
int age_sum = human_a.age + human_b.age;
return age_sum;
}
Nom d’espace
On respecte toujours le plus possible le principe de responsabilité unique, ce qui conduit à une réduction de la différence de taille entre les espaces et les (ou la) classes qu’ils contiennent.
Pour éviter les confusions entre le nom de l’espace et le nom de la classe, on adapte le nom d’espace en lui ajoutant les lettres “NS” pour “NameSpace”.
On donne priorité à la classe, c’est donc le nom d’espace qui est adapté.
Avec le principe de “Directive Using obligatoire en début de fichier”, le nom d’espace est utilisé uniquement en début de fichier.
namespace NS_Math
{
public class Math
{
}
}
namespace NS_Math.NS_Geometry
{
public class Geometry
{
}
}
Priorité des mots séparateurs
Les mots séparateurs sont conçus pour toujours donner les mêmes séparations logiques.
Les séparateurs “from” et “get” sont les séparateurs de plus haut niveau, ils indiquent le point d’entrée et de sortie d’une fonction.
public static int from_human_get_age (Human human)
{
int age = human.age;
return age;
}
Le séparateur “and” indique une séparation entre variables.
public static float from_alpha_and_beta_get_addition (int alpha, int beta)
{
int addition = alpha + beta;
return addition;
}
public static float from_alpha_and_beta_and_gamma_get_addition (int alpha, int beta, int gamma)
{
int addition = alpha + beta + gamma;
return addition;
}
Le séparateur “with” ajoute des caractéristiques à une variable.
public static int from_human_with_hat_get_age (Human human_with_hat)
{
int age = human_with_hat.age;
return age;
}
public static int from_human_with_hat_with_tie_get_age (Human human_with_hat_with_tie)
{
int age = human_with_hat_with_tie.age;
return age;
}
Le séparateur “whose” indique la caractéristique d’une variable à laquelle on s’intéresse. Le séparateur “whose” est souvent implicite. Dans les cas complexes, il est recommandé d’écrire le séparateur “whose” de façon explicite.
Les fonctions suivantes sont toutes équivalentes :
public static int from_human_get_human_whose_age (Human human)
{
int human_whose_age = human.age;
return human_whose_age;
}
public static int from_human_get_human_age (Human human)
{
int human_age = human.age;
return human_age;
}
public static int from_human_get_age (Human human)
{
int age = human.age;
return age;
}
Le sépateur “plus” indique une séparation entre composants d’un conteneur.
Dictionary<string, int=""> dico_name_plus_age;
KeyValuePair<string, int=""> kvp_name_plus_age</string,></string,>
Exemple
Le nom de fonction suivant :
from_human_with_hat_with_dog_and_umbrella_get_color
se décompose de la façon suivante :
FROM ( human WITH ( hat , dog ) AND umbrella ) GET ( color )
Une utilisation du nom de fonction :
// ce nom de fonction ne précise pas quelle couleur on veut obtenir
public Color
from_human_with_hat_with_dog_and_umbrella_get_color (
Human human_with_hat_with_dog,
Umbrella umbrella)
{
Color color = human_with_hat_with_dog.dog.color;
return color;
}
// ce nom de fonction précise que la couleur recherchée est celle de "dog".
public Color
from_human_with_hat_with_dog_and_umbrella_get_dog_color (
Human human_with_hat_with_dog,
Umbrella umbrella)
{
Color color = human_with_hat_with_dog.dog.color;
return color;
}
// ce nom de fonction précise que la couleur recherchée est celle de "umbrella".
public Color
from_human_with_hat_with_dog_and_umbrella_get_umbrella_color (
Human human_with_hat_with_dog,
Umbrella umbrella)
{
Color umbrella_color = umbrella.color;
return umbrella_color;
}
// ce nom de fonction précise que c'est une liste de couleurs qui est recherchée.
public List<color>
from_human_with_hat_with_dog_and_umbrella_get_list_color (
Human human_with_hat_with_dog,
Umbrella umbrella)
{
List<color> list_color = new List<color> ()
{
human_with_hat_with_dog.color,
human_with_hat_with_dog.hat.color,
human_with_hat_with_dog.dog.color,
umbrella.color
};
return list_color;
}