Les exceptions sont-elles un concept de POO?

37

Après avoir lu un article hier, j'ai réalisé que je ne connaissais pas grand chose sur l'origine des exceptions. S'agit-il uniquement d'un concept lié à la POO? J'ai tendance à penser que c'est le cas, mais encore une fois, il existe des exceptions de base de données.

John V
la source
J'ai lu un jour qu'un "Mr Goodenuf" (ou similaire) avait inventé les exceptions en réponse à "peu importe, c'est Goodenuf, hein!" intimidation de style. Je n'arrive pas à trouver une référence maintenant - peut-être que quelqu'un d'autre peut le faire. Il serait intéressant de savoir à quelle langue ils ont été ajoutés en premier.
Steve314
7
Haskell a des exceptions et ce n'est pas du tout la POO
Daniel Gratzer le
1
Bien que les exceptions elles-mêmes ne soient pas strictement orientées objet, la pratique courante qui consiste à définir des exceptions en tant qu’objets et à lancer et intercepter des instances de ces objets est très pratique.
Dougvj
Quelle est la différence entre une exception et un GOTO serait une question intéressante.
Austin Henley
2
@ Austin - que diriez-vous de "bien que les jets d'exception violent le principe du point de sortie unique selon lequel certains des disciples les plus stricts des partisans de la programmation structurée défendent comme un absolu, ils ne permettent pas un flux de contrôle des spaghettis sans contrainte de cette manière goto. la portée est déterminée par le contexte, en fonction de l'imbrication de structures de blocs. De ce fait, les exceptions dépendent même d'une forme légèrement moins stricte de programmation structurée où le principe de la sortie unique est pris comme référence, mais non comme absolu ".
Steve314

Réponses:

5

Les exceptions ne sont pas un concept OOP.

Mais ils ne sont pas non plus complètement indépendants l'un de l'autre.

Comme d’autres réponses l’ont montré: Le concept d’exception s’applique dans plusieurs langues autres que la programmation orientée objet. Rien dans ce concept n'exige quelque chose de la programmation orientée objet.

Cependant, tous les langages POO, si ce n'est tous, qui prennent sérieusement la POO requièrent des exceptions car les autres méthodes de traitement des erreurs échouent à un point spécifique: le constructeur.

Un des points de la programmation orientée objet est qu'un objet doit encapsuler et gérer son état interne de manière complète et cohérente. Cela signifie également qu'en pure POO, vous avez besoin d'un concept pour créer un nouvel objet avec un état cohérent "de manière atomique" - tout, de l'allocation de mémoire (si nécessaire) à l'initialisation à un état significatif (la mise à zéro de la mémoire ne suffit pas). être fait en une seule expression. Un constructeur est donc nécessaire:

Foo myFoo = Foo("foo", "bar", 42);

Mais cela signifie que le constructeur peut également échouer à cause d'une erreur. Comment propager l'information d'erreur du constructeur sans exception?

  • Valeur de retour? Echoue car dans certaines langues, newseule nullune information significative peut être renvoyée. Dans d'autres langages (par exemple, C ++), ce myFoon'est pas un pointeur. Vous ne pouviez pas le vérifier null. Aussi, vous ne pouvez pas poser myFoode question sur l'erreur - elle n'est pas initialisée et donc "n'existe pas" dans la pensée de la programmation orientée objet.

  • Indicateur d'erreur globale? Tant de choses sur l'état d'encapsulation et ensuite une variable globale? Allez à h ... ;-)

  • Un mélange? En aucun cas mieux.

  • ?

Les exceptions sont donc un concept plus fondamental que la POO, mais la POO les construit de manière naturelle.

AH
la source
3
pour autant que je sache, le seul mot de cette "réponse" qui répond à la question posée est "non". Le reste semble concerner des exceptions en POO - avec tout le respect que je vous dois, cela se situe quelque part entre vaguement lié et totalement dénué de pertinence - de nouveau, dans le contexte de la question posée
gnat le
@gnat: le TO dit également qu'il ne connaît pas l'origine des exceptions. Par conséquent, un peu de contexte sur la raison pour laquelle les exceptions sont omniprésentes dans OO semblait me convenir. YMMV
AH
1
@AH Je suis d'accord avec gnat, à part la première ligne, cela ne règle vraiment pas la question. Votre réponse à gnat était "dit qu'il ne connaissait pas l'origine des exceptions", mais vous ne lui avez pas indiqué l'origine de ces exceptions, mais simplement l'utilisation aléatoire d'exceptions lors de l'instanciation d'un objet.
Les gars, sérieusement? -1? La plupart des autres réponses ne sont pas à 100%, non plus. +1 de moi pour compenser. Cette réponse donne de bons conseils de base dans un monde de conceptions de classe brisées. (Amendement: Mentionnez les constructeurs multi-étapes à éviter)
Jo So
44

Est-ce seulement lié à la POO?

Non. Les exceptions et la POO ne sont pas liées.

La gestion des exceptions est un mécanisme permettant de gérer les erreurs. Une exception est gérée en sauvegardant l'état d'exécution actuel dans un emplacement prédéfini et en basculant l'exécution vers un sous-programme spécifique appelé gestionnaire d'exceptions.

En comparant le langage C ( pas vraiment le langage OOP , il est possible d’émuler les exceptions en C ) et le C ++ (OOP, prend en charge les exceptions), rien n’empêche le comité standard de C d’ajouter le traitement des exceptions à C, il ne fera toujours pas de C un langage OOP.

BЈовић
la source
2
Vous pourriez même dire qu'il existe déjà une sorte d'exception prise en charge dans le système d'exploitation habituel. Laissez votre programme se bloquer ("l'exception" non capturée) et avec un vidage de la base et un débogueur, vous obtenez même une trace de pile.
Bonjour
12
Même MS BASIC du début des années 80 avait une gestion des exceptions:ON ERROR GOTO xxxx
jwernerny
1
@bhaak Il pourrait aussi parler de dumps de mémoire dans Windows
JohnL
11
@jwernerny Gestion des erreurs? Sûr. Mais personne n’appellerait cela une exception. En fait, il était couramment mis en contraste avec la gestion des exceptions (structurée).
Konrad Rudolph
1
@jwernerny pas sûr que je suive; la gestion des exceptions telle que je l'ai comprise est une manière très spécifique de gérer les erreurs. Quand j'entends l'exception, je pense toujours à la try catchconstruction.
Andy
12

Une exception est simplement une situation exceptionnelle qui nécessite une attention et souvent un changement dans le déroulement de l’exécution d’un programme. Selon cette définition, la gestion des exceptions et des exceptions ne se limite pas à l'orientation objet, et les erreurs de programme simples peuvent être considérées comme une forme d'exception.

Les langages orientés objet ont généralement une classe d'exception native et, en fonction du contexte, le mot "exception" peut en fait faire référence à cette classe native au lieu du concept général. La gestion des exceptions orientée objet est, comme l'essentiel de l'orientation objet, un sucre syntaxique, et peut être facilement imitée dans des langages résolument non orientés objet. Voici un exemple en C, tiré du wikibook Programmation C :

#include <stdio.h>
#include <setjmp.h>

jmp_buf test1;

void tryjump()
{
    longjmp(test1, 3);
}

int main (void)
{
    if (setjmp(test1)==0) {
        printf ("setjmp() returned 0.");
        tryjump();
    } else {
        printf ("setjmp returned from a longjmp function call.");
    }
}
Yannis
la source
6
Ce n'est pas simplement du sucre syntaxique. Recréer une pile complète déroulant et des gestionnaires de capture basés sur des types est difficile avec setjmp. De plus, la compilation spécialisée des exceptions offre des avantages qui ne peuvent pas être simulés par setjmp.
edA-qa mort-ora-y
3
Je déteste les exceptions de description sont des situations exceptionnelles. Je dirais plutôt que des exceptions devraient être générées (levées) lorsqu'une situation d'erreur ne peut pas être résolue avec le contexte actuel car il n'y a pas assez d'informations dans le contexte actuel pour corriger correctement l'erreur.
Martin York
+1 pour setjmp.h
gnat
9

La réponse est un simple NON.

ADA est un bon exemple de langage non-OO avec des exceptions.

Uwe Plonus
la source
4
Hm, pourquoi ADA n'est pas une langue OO? Certes, ADA83 manquait de polymorphisme, mais il pourrait toujours être considéré comme basé sur les objets. De plus, depuis ADA95, le langage est entièrement orienté objet.
Yannis
Pour autant que je sache, la gestion des exceptions est antérieure à ADA83 et par conséquent, ADA est en soi un non-OO avec une gestion des exceptions.
Uwe Plonus
2
@YannisRizos: Ada83 a des packages et des packages génériques, mais pas d'objets. Ils ont été introduits avec Ada95.
mouviciel
2
@Yannis - Les objets sans polymorphisme sont comme une programmation structurée sans blocs imbriqués. Le polymorphisme est l’un des traits caractéristiques de la POO. Même dans Ada95, les types qui prennent en charge la liaison au moment de l’exécution sont appelés «types marqués» plutôt que «classes», bien que ce ne soit bien sûr que l’orthographe. Ada 83 avait des enregistrements de variantes et divers autres types, mais aucun de ces types ne fournit de fonctionnalités spécifiques à la POO. Ada 83 était modulaire et structuré, mais il n'était pas orienté objet.
Steve314
3
@Yannis - En gros, certains membres de la communauté Ada (comme certains défenseurs de la plupart des langues) ne peuvent pas accepter le fait qu'une fonctionnalité puisse être bonne sans être implémentée dans leur langue préférée et invente toutes sortes d'excuses pour croire le contraire. Pourtant, ce n’est même pas comme si un bon langage avait besoin de toutes les fonctionnalités possibles (même s’il était facile de croire que les concepteurs d’Ada le pensaient). Je ne crois pas vraiment à l'approche minimaliste de la conception linguistique, mais les langues maximalistes ne sont pas parfaites non plus.
Steve314
7

Quelques très bonnes réponses ici déjà. Autres exemples de langages de programmation non-POO ayant des exceptions:

  • Oracle PL / SQL

  • Visual Basic classique (V6 et inférieur, "On Error Goto" est, à mon sens, une forme de gestion des exceptions)

(Pour être précis: vous trouvez des éléments OO dans les deux langues, mais le mécanisme de traitement des exceptions ne les utilise pas, je suppose, car le concept a été introduit des années avant l'ajout des éléments OO à ces langues).

Doc Brown
la source
Au moins les dernières versions de QuickBASIC sous DOS (antérieures à Visual Basic; QB 4.5 était 1988 d'après Wikipedia, VB 1.0 1991) comportaient une gestion des erreurs à l'aide de la ON ERROR GOTOsyntaxe. Même QuickBASIC avait quelques concepts similaires à OO (je pense que QB 4.5 supportait même des classes), mais vous auriez bien du mal à appeler BASIC, un langage essentiellement traditionnel, un vrai langage orienté objet. [Wikipedia ]
un CVn
5

L'idée de base derrière les exceptions est de nettoyer le flux du programme afin qu'un programmeur puisse suivre plus facilement le chemin d'exécution "normal". Prenons un cas simple d’ouverture d’un fichier en C. Immédiatement après avoir tenté d’ouvrir le fichier, le programmeur doit examiner la réponse de l’appel fopen () et décider s’il a réussi. Si l'appel n'a pas abouti, le programmeur doit répondre correctement. Le prochain appel dans le chemin d'exécution "normal", peut-être un appel à fread () ou à fwrite (), apparaîtra une fois que les conditions d'erreur ou d'échec auront été gérées. Cela peut être sur l'écran suivant.

Avec un langage fournissant des exceptions, l'appel fopen () équivalent peut être suivi immédiatement par fread () ou fwrite (). Il n'y a pas de traitement d'erreur qui cache la "prochaine étape" du chemin d'exécution "normal". Le programmeur peut voir plus du chemin normal sur un seul écran, et peut donc suivre l'exécution plus facilement. La gestion des erreurs est déplacée vers une autre partie du programme.

Les exceptions elles-mêmes ne sont pas un concept de programmation orientée objet, mais elles sont souvent mises en œuvre à l'aide de concepts de programmation orientée objet qui les rendent plus pratiques et plus puissantes. Par exemple, les exceptions peuvent être définies avec une hiérarchie d'héritage. En utilisant notre exemple théorique d'ouverture et de lecture ou d'écriture d'un fichier, chacun de ces appels peut générer diverses exceptions - FileClosedException, DeviceFullException, NoSuchFileException, InsufficientFilePermissionsException, etc. Chacun de ces appels peut hériter de FileException, qui peut hériter de IOException, qui peut hériter de GenericException.

Si le programmeur effectue une mise en œuvre rapide et incorrecte pour tester un concept, il peut en grande partie ignorer la gestion des exceptions et simplement mettre en œuvre un gestionnaire unique pour GenericException. Ce gestionnaire gérera une exception GenericException et toute exception héritant de GenericException. S'il veut traiter n'importe quelle exception liée au fichier de la même manière, il peut écrire un gestionnaire pour FileException. Cela sera appelé pour FileExceptions et toutes les exceptions héritant de FileException. S'il veut écrire un programme qui répondra différemment à diverses conditions d'erreur, il peut écrire un gestionnaire spécifique pour chaque exception spécifique.

MikeD
la source
3

D'autres ont à juste titre répondu «non» avec des exemples de langues. Je pensais pouvoir étendre mon propos en ajoutant un exemple sur la manière d’ajouter des exceptions à une langue sans jamais impliquer la POO.

Je le ferai dans le cas du langage DSKL (langage déclaratif du noyau séquentiel) d' OZ , un langage bien adapté à la vie académique comme celle-ci. Le DSKL (ou DKL) peut être vu ici (résultat de la recherche aléatoire), la partie Déclarations et valeurs. La définition exacte n’est pas importante, à part qu’il s’agit d’un langage très simple, sans variables modifiables (elles sont déclarées et ensuite liées), et pas de POO intégrée.

La programmation orientée objet ne peut même pas être ajoutée en tant qu'abstraction linguistique à cette langue du noyau. En ajoutant des noms uniques à la langue du noyau (NewName) et en utilisant la portée locale, l’encapsulation peut être réalisée. Ou en ajoutant un état modifiable à la langue du noyau (NewCell) et en utilisant une OOP de portée locale avec encapsulation appropriée. Mais cela ne peut pas être réalisé avec la seule langue du noyau spécifiée.

Si nous ajoutons ensuite des exceptions à la langue du noyau, nous aurons une langue sans prise en charge de la POO mais avec des exceptions. Laissez-moi vous montrer comment:

En définissant une machine abstraite avec une pile et un stockage, nous pouvons définir ce que chaque instruction de notre langage doit faire (la sémantique de l’instruction). Par exemple, skipdans la pile ne devrait rien faire, A = 3dans la pile devrait lier (/ unifier) ​​A à (/ avec) 3.

Nous commençons par ajouter la syntaxe de la manière dont nos exceptions doivent être définies. Pour ce faire, nous ajoutons deux autres clauses à <statement>la DKL.

<statement>  ::== ... (old stuff)
                 | try <statement> catch <id> then <statement> end
                 | raise <id> end

Voici le try / catch connu et un moyen de lever / jeter des exceptions.

Nous définissons leur sémantique par la façon dont ils devraient travailler sur la machine abstraite:

Try
La déclaration sémantique est: (try <statement1> catch <id> then <statement2> end)
Do:

  1. Poussez sur la pile la déclaration sémantique (catch <id> then <statement2> end)
  2. Poussez sur la pile la déclaration sémantique (<statement1>)

Notez que l'instruction 1 sera au-dessus de la pile et sera exécutée en premier.

Raise
L'énoncé sémantique est: (raise <id> end)
Do:

  1. Si rien ne se trouve sur la pile, arrêtez et signalez une exception non capturée.
  2. Sinon, extrayez la première déclaration sémantique de la pile. Si ce n'est pas une déclaration de capture, passez à l'étape 1.
  3. Nous avons un piège, sur le formulaire (catch <id> then <statement> end)
    Poussez (<statement>)sur la pile.

Catch
Si nous voyons une instruction catch lors de l'exécution normale, cela signifie que tout ce qui était à l'intérieur a été exécuté sans générer d'exceptions jusqu'à ce niveau. Ainsi, nous sortons simplement catchde la pile et ne faisons rien.

CQFD, nous avons un langage avec des exceptions et aucune possibilité de POO.

J'ai supprimé la partie environnement de la machine abstraite pour la simplifier.

Matsemann
la source
1

Non.

IIRC, des exceptions sont apparues avant les premières langues OO. D'après les informations dont je dispose, les exceptions ont d'abord été prises en charge par les premières implémentations de LISP. Les premiers langages structurés (par exemple ALGOL) et les premiers langages OO (par exemple SIMULA) ne prenaient pas en charge les exceptions.

Kevin Cline
la source
ALGON 68, bien sûr, avait des exceptions ("événements"), mais il y avait tout le reste aussi. PL / I les avait aussi ("ON conditions") et il existe une littérature de 1969 décrivant leur utilisation.
Ross Patterson