Programmation non orientée objet en langage orienté objet [fermé]


15

Récemment, j'ai été chargé de créer une calculatrice avec des fonctions d'addition, de soustraction, de multiplication, de division et de puissance à l'aide de la programmation orientée objet . J'ai réussi cette tâche. Cependant, par la suite, j'ai reprogrammé tout le programme sans utiliser la technique / méthode orientée objet .

La chose que j'ai remarquée, c'est que la longueur de mon code a été réduite de manière assez significative et c'était assez compréhensible. Donc ma question ici est quand dois-je utiliser la programmation orientée objet? Est-il correct de créer des programmes sans orientation objet dans un langage orienté objet? Veuillez m'aider sur celui-ci.

PS: Je ne demande pas ici de me dire les mérites de la programmation orientée objet par rapport à la programmation procédurale.


12
Il n'y a absolument aucune raison d'éviter d'appliquer différentes techniques selon les besoins. En tant que programmeur, vous devrez peser le pour et le contre au cas par cas. Très souvent, cela se résume à un style personnel.
ChaosPandion

3
Je n'ai jamais eu de problème. La langue était presque toujours un outil prescrit étant donné l'équipe et / ou une autre architecture.


8
La mise en œuvre du même programme avec et sans techniques OO est un bon exercice pour apprendre quelque chose, je ne comprends pas pourquoi certaines personnes ici semblent le nier ou vous dévaloriser. Mais le problème avec votre question est qu'elle a déjà été posée ici plus d'une fois, sous différentes formes. Et si vous refusez, vous êtes posez sur les mérites de la programmation orientée objet sur la programmation procédurale. Et C ++ n'est pas un langage OO, c'est un langage hybride.
Doc Brown

3
Ajoutez une fonction qui affiche la formule que vous avez entrée, puis ajoutez une fonction de racine carrée (ne faites pas cela d'abord, ce serait de la triche.) Et faites-nous savoir ce que vous pensez.
JeffO

Réponses:


25

Le C ++ n'est pas "juste" un langage OO, c'est un langage multi-paradigme. Cela vous permet donc de décider pour ou contre la programmation OO, ou de les mélanger les deux. L'utilisation de techniques OO ajoute plus de structure à votre programme - dont vous bénéficierez lorsque votre programme atteindra une certaine taille ou complexité. Cette structure supplémentaire, cependant, vient au prix de lignes de code supplémentaires. Ainsi, pour les "petits" programmes, la meilleure façon de procéder consiste souvent à les mettre en œuvre dans un style non OO en premier, et à ajouter de plus en plus de techniques OO plus tard lorsque le programme commence à se développer au fil des ans (ce qui n'arrivera probablement pas à "l'exercice"). "programmes, mais c'est le cycle de vie typique de nombreux programmes d'entreprise).

La partie délicate est de ne pas manquer le moment où la complexité de votre programme atteint la taille qui nécessite plus de structure. Sinon, vous vous retrouverez avec une énorme pile de code de spaghetti.


Si de simples programmes "d'exercices" commencent à évoluer, le meilleur moyen est de le mettre en œuvre de telle manière qu'il puisse être refacturé par la suite. Merci d'avoir partagé cela :) +1
FaizanRabbani

@CarlSmith: absolument. Mais quand j'ai écrit ma réponse, j'ai essayé de me concentrer sur les points et l'échelle de la question réelle.
Doc Brown

10

Comment les programmeurs professionnels font-ils appel au jugement pour opter ou non pour la POO? Ce serait vraiment utile pour moi.

Pour moi, il y a deux points de décision. Tout d'abord, parfois, cela sera évident au début. Il y aura beaucoup de types similaires qui partagent tous des méthodes communes qui diffèrent considérablement dans leurs détails d'implémentation. Par exemple, je construisais un système de workflow et j'avais besoin de pouvoir implémenter des tâches arbitraires. Pour exécuter la tâche, j'ai implémenté une classe de base dont chaque tâche a hérité, avec une Execute()méthode abstraite. Les classes héritées fournissaient l'implémentation, mais le système de workflow pouvait commencer l'exécution sans rien savoir du type de tâche en cours d'exécution.

Cependant, la plupart des projets ne sont pas aussi clairs. Le deuxième point de décision est lorsqu'un sous-ensemble du projet est devenu un énorme enchevêtrement d'instructions if-then ou d'instructions switch-case, et surtout lorsque ces instructions if-then nécessitent beaucoup de code de configuration pour fonctionner correctement. Je me sens commencer à perdre la logique de ce que j'essaie d'accomplir, et le code commence à se sentir fragile. À ce stade, c'est généralement un signe qu'il est temps de refactoriser le code en classes de base avec des implémentations spécifiques.

Une grande partie du passage à un style orienté objet par opposition à un style fonctionnel consiste à convertir les instructions if-then en instructions "exécuter cette action". Au lieu d'un énorme ensemble d'instructions if-then, vous dites simplement au code d'exécuter son action. L'action réellement exécutée dépend de l'implémentation que vous avez fournie.

Par exemple, voici le style fonctionnel du pseudocode de style C #:

if ( action == "email" ) { 
    callEmailFunction(userInfo);
}
else if ( action == "sms" ) { 
    callSmsFunction(userInfo);
}
else if ( action == "web" ) { 
    endpoint = "http://127.0.0.1/confirm";
    confirmWeb(endpoint, userinfo);
} 
...

Mais peut-être pourriez-vous réécrire cela à quelque chose comme ceci:

interface IConfirmable {
    void Confirm(UserInfo userinfo);
}

public class ConfirmEmail : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmSms : IConfirmable { 
    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via email
    }
}

public class ConfirmWeb : IConfirmable { 
    // this is a constructor
    public ConfirmWeb(string endpoint) { 
        ...
    }

    public void Confirm(UserInfo userinfo) {
        // do the appropriate thing to confirm via web
    }
} 

Et puis le code lui-même:

// An implementation that decides which implementation of the base class to use
// This replaces the if-then statements in the functional programmming.
IConfirmable confirmer = ConfirmerFactory.GetConfirmer();

// get the userinfo however you get it, 
// which would be the same way you get it in the functional example.
UserInfo userinfo = ...;

// perform the action.
confirmer.Confirm(userinfo);

Maintenant, quand il y a très peu de code à l'intérieur du if-then, cela ressemble à beaucoup de travail pour n'en tirer aucun avantage. Et quand il y a très peu de code dans le si-alors, c'est correct: c'est beaucoup de travail pour le code qui est plus difficile à comprendre.

Mais le style orienté objet brille vraiment lorsque vous avez plus d'une action que la Confirm()méthode qui doit être exécutée. Vous disposez peut-être d'une routine d'initialisation, de trois méthodes d'action ou plus pouvant être exécutées et d'une Cleanup()méthode. L'algorithme de base est identique, sauf qu'il effectue ses appels dans les objets appropriés qui implémentent une classe de base commune. Maintenant, vous commencez à voir un réel avantage pour le style orienté objet: l'algorithme de base est beaucoup plus facile à lire que s'il vérifiait les instructions if-then à chaque étape du processus.


+1 pour une analyse détaillée. :) J'ai quelques réflexions à ce sujet.
FaizanRabbani

1
Mis à part: veuillez cesser de poster des commentaires de "merci" sur chaque réponse. Nous préférons nous concentrer uniquement sur les questions et réponses, pas sur la discussion.
Philip Kendall

5
Cet exemple est plus impératif que fonctionnel.
OrangeDog


1
Juste une note, lorsque vous vous penchez vers un tas d'instructions if / else ou switch, c'est toujours une option pour envisager une sorte de table de recherche. Donc, une autre façon de réécrire qui va dans le sens de var dict = new Dictionary<string,Action<UserInfo>{ { "email", callEmailFunction }, { "sms", callSmsFunction } }; dict[ action ]( userInfo );(dict peut être statique, la gestion des erreurs omise)
stijn

3

Oui, il est parfaitement normal d'utiliser du code à l'ancienne, à condition que la portée de votre projet soit bien connue ou limitée. Si vous prévoyez d'étendre votre programme ou projet, la POO est une solution, car vous pouvez maintenir et étendre votre code de manière transparente, d'autre part, si vous l'avez planifié et que vous êtes parvenu à la conclusion que vous ne planifierez jamais l'extensibilité de la projet que vous faites puis écrire du code sans POO suffirait. Cela ne signifie pas que si vous utilisez une approche non OOP, vous ne pouvez jamais mettre à niveau votre projet, mais ce serait une chose fastidieuse à faire. La POO est de nous aider à visualiser notre concept comme s'il s'agissait d'un organisme réel parce que nous les comprenons mieux qu'autre chose.


1
"Cela ne signifie pas que si vous utilisez une approche non OOP, vous ne pouvez jamais mettre à niveau votre projet, mais ce serait une chose fastidieuse à faire.": OOP aide à étendre votre projet lorsque la plupart des extensions impliquent l'ajout de nouvelles classes (par exemple, l'ajout de nouveaux widgets à une interface graphique). Lorsque la plupart des extensions impliquent l'ajout de nouvelles opérations, une conception procédurale peut être plus efficace.
Giorgio

1
Depuis quand "n'est pas orienté objet" appelé "ancien style"?
DanielSank
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.