Programowanie bez obiektowe w języku obiektowym [zamknięte]

15

Ostatnio przydzielono mi zadanie tworzenia kalkulatora z dodawaniem, odejmowaniem, mnożeniem, dzieleniem i mocą funkcji za pomocą programowania obiektowego . Pomyślnie ukończyłem to zadanie. Jednak później przeprogramowałem cały program bez użycia techniki / metody Object Oriented .

Zauważyłem, że długość mojego kodu została znacznie zmniejszona i było całkiem zrozumiałe. Więc moje pytanie brzmi, kiedy powinienem używać programowania obiektowego? Czy można tworzyć programy bez orientacji obiektowej w języku obiektowym? Prosimy mi pomóc w tej sprawie.

PS: Nie pytam tutaj, aby powiedzieć mi zalety programowania obiektowego w porównaniu z programowaniem proceduralnym.

FaizanRabbani
źródło
12
Nie ma absolutnie żadnego powodu, aby unikać stosowania różnych technik w razie potrzeby. Jako programista będziesz musiał rozważyć zalety i wady poszczególnych przypadków. Dość często sprowadza się to do osobistego stylu.
ChaosPandion,
3
Nigdy nie miałem problemu. Język był prawie zawsze zalecanym narzędziem ze względu na zespół i / lub inną architekturę.
8
Wdrożenie tego samego programu z technikami OO i bez nich jest dobrym ćwiczeniem, aby się czegoś nauczyć. Nie rozumiem, dlaczego niektórzy ludzie tutaj zaprzeczają temu lub głosują za tobą. Ale problem z twoim pytaniem polega na tym, że zadawano go tu więcej niż raz, w różnych formach. I choć zaprzeczyć, to pytając o meritum Object Oriented Programming ponad programowanie proceduralne. A C ++ nie jest językiem OO, jest językiem hybrydowym.
Doc Brown
3
Dodaj funkcję, która wyświetla wprowadzoną formułę, a następnie dodaj funkcję pierwiastka kwadratowego (Nie rób tego najpierw, to byłoby oszustwo) i daj nam znać, co myślisz.
JeffO

Odpowiedzi:

25

C ++ nie jest „tylko” językiem OO, jest językiem o wielu paradygmatach. Dzięki temu możesz decydować za lub przeciw programowaniu OO lub mieszać je oba. Korzystanie z technik OO dodaje więcej struktury do twojego programu - z czego skorzystasz, gdy twój program osiągnie określony rozmiar lub złożoność. Ta dodatkowa struktura występuje jednak w cenie dodatkowych wierszy kodu. Tak więc w przypadku „małych” programów najlepszym sposobem jest często wdrożenie ich najpierw w stylu innym niż OO, a następnie dodawanie coraz większej liczby technik OO później, gdy program zacznie się rozwijać z biegiem lat (co prawdopodobnie nie przyda się podczas ćwiczeń) „programy, ale jest to typowy cykl życia wielu programów biznesowych).

Trudność polega na tym, aby nie przegapić momentu, w którym złożoność programu osiągnie rozmiar wymagający większej struktury. W przeciwnym razie skończysz z ogromną stertą kodu spaghetti.

Doktor Brown
źródło
Jeśli proste programy „ćwiczeniowe” zaczynają ewoluować, najlepszym sposobem jest ich wdrożenie w taki sposób, aby można je było później ponownie uwzględnić. Dziękujemy za udostępnienie tego :) +1
FaizanRabbani
@CarlSmith: absolutnie. Ale kiedy napisałem swoją odpowiedź, starałem się skupić na punktach i skali rzeczywistego pytania.
Doc Brown
10

Jak profesjonalni programiści oceniają, czy wybrać OOP, czy nie? Byłoby to dla mnie bardzo pomocne.

Dla mnie są dwa punkty decyzji. Po pierwsze, czasami będzie to oczywiste na początku. Będzie wiele podobnych typów, z których wszystkie mają wspólne metody, które różnią się znacznie szczegółami ich implementacji. Na przykład budowałem system przepływu pracy i potrzebowałem umiejętności realizacji dowolnych zadań. Aby uruchomić zadanie, zaimplementowałem klasę podstawową, z której każde zadanie dziedziczyło, za pomocą Execute()metody abstrakcyjnej. Klasy dziedziczące dostarczyły implementację, ale system przepływu pracy mógł rozpocząć wykonywanie, nie wiedząc nic o rodzaju wykonywanego zadania.

Większość projektów nie jest jednak tak jednoznaczna. Drugi punkt decyzji ma miejsce, gdy podzbiór projektu urósł do ogromnej plątaniny instrukcji if-then lub instrukcji case-switch, a zwłaszcza gdy te instrukcje if-then wymagają dużej ilości kodu instalacyjnego do poprawnego działania. Czuję, że zaczynam tracić logikę tego, co próbuję osiągnąć, a kod zaczyna być kruchy. W tym momencie zwykle jest to znak, że nadszedł czas, aby przefakturować kod na klasy podstawowe z konkretnymi implementacjami.

Dużą częścią przejścia na styl obiektowy w przeciwieństwie do stylu funkcjonalnego jest przekształcanie instrukcji if-then w instrukcje „uruchom tę akcję”. Zamiast ogromnego zestawu instrukcji „jeśli-to”, po prostu mówisz kodowi, aby uruchomił swoją akcję. To, które działanie jest faktycznie wykonywane, zależy od dostarczonej implementacji.

Na przykład, oto funkcjonalny styl w pseudokodzie w stylu 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);
} 
...

Ale może mógłbyś przepisać to na coś takiego:

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
    }
} 

A potem sam kod:

// 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);

Teraz, gdy w kodzie if-wtedy jest bardzo mało kodu, wygląda to na dużo pracy, która nie przynosi korzyści. A kiedy w kodzie if-wtedy jest bardzo mało kodu, jest to poprawne: jest to dużo pracy dla kodu, który jest trudniejszy do zrozumienia.

Ale styl zorientowany obiektowo naprawdę świeci, gdy masz więcej niż jedną akcję, niż tylko Confirm()metodę, którą należy wykonać. Być może masz procedurę inicjalizacji, trzy lub więcej metod działania, które można uruchomić, oraz Cleanup()metodę. Algorytm podstawowy jest identyczny, z tym wyjątkiem, że wywołuje wywołania w odpowiednie obiekty, które implementują wspólną klasę podstawową. Teraz zaczynasz dostrzegać prawdziwą korzyść ze stylu obiektowego: algorytm bazowy jest znacznie łatwiejszy do odczytania, niż gdyby sprawdzał instrukcje „jeśli-to” na każdym etapie.

Charlie Kilian
źródło
+1 za szczegółową analizę. :) Mam kilka przemyśleń na ten temat.
FaizanRabbani
1
Poza tym: proszę przestać publikować komentarze „dziękuję” do każdej odpowiedzi. Wolimy skupiać się tylko na pytaniach i odpowiedziach, a nie na dyskusji.
Philip Kendall,
5
Ten przykład jest bardziej konieczny niż funkcjonalny.
OrangeDog,
1
Tylko uwaga, kiedy skłaniasz się w kierunku zbioru instrukcji if / else lub switch, zawsze możesz rozważyć jakąś tabelę lookup. Więc inny sposób na przepisanie, który jest var dict = new Dictionary<string,Action<UserInfo>{ { "email", callEmailFunction }, { "sms", callSmsFunction } }; dict[ action ]( userInfo );
zgodny
3

Tak, używanie kodu w starym stylu jest całkowicie normalne, pod warunkiem, że zakres projektu jest dobrze znany lub ograniczony. Jeśli planujesz rozszerzyć swój program lub projekt, OOP jest jednym ze sposobów, ponieważ możesz bezproblemowo utrzymywać i rozszerzać swój kod, z drugiej strony, jeśli go zaplanowałeś i doszedłeś do wniosku, że nigdy nie planujesz rozszerzenia możliwości wystarczy wykonać projekt, a następnie napisanie kodu bez OOP. Nie oznacza to, że jeśli zastosujesz podejście inne niż OOP, nigdy nie możesz uaktualnić swojego projektu, ale byłoby to żmudne. OOP ma pomóc nam w wizualizacji naszej koncepcji, tak jakby to był prawdziwy organizm, ponieważ rozumiemy je lepiej niż cokolwiek innego.

użytkownik50927
źródło
1
„Nie oznacza to, że jeśli zastosujesz podejście inne niż OOP, nigdy nie możesz uaktualnić swojego projektu, ale byłoby to żmudne.”: OOP pomaga przedłużyć projekt, gdy większość rozszerzeń wymaga dodania nowych klas (np. Dodanie nowych widżetów do GUI). Gdy większość rozszerzeń wymaga dodawania nowych operacji, projektowanie proceduralne może być bardziej skuteczne.
Giorgio
1
Od kiedy „nie zorientowany obiektowo” nazywa się „starym stylem”?
DanielSank,