window.pipedriveLeadboosterConfig = { basis: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', versie: 2, } ;(functie () { var w = venster als (w.LeadBooster) { console.warn('LeadBooster bestaat al') } anders { w.LeadBooster = { q: [], on: functie (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: functie (n) { this.q.push({ t: 't', n: n }) }, } } })() Objectgeoriënteerd programmeren. Zo denk je niet - The Codest
The Codest
  • Over ons
  • Diensten
    • Software Ontwikkeling
      • Frontend ontwikkeling
      • Backend ontwikkeling
    • Staff Augmentation
      • Frontend ontwikkelaars
      • Backend ontwikkelaars
      • Gegevensingenieurs
      • Cloud Ingenieurs
      • QA ingenieurs
      • Andere
    • Het advies
      • Audit & Consulting
  • Industrie
    • Fintech & Bankieren
    • E-commerce
    • Adtech
    • Gezondheidstechnologie
    • Productie
    • Logistiek
    • Automotive
    • IOT
  • Waarde voor
    • CEO
    • CTO
    • Leveringsmanager
  • Ons team
  • Case Studies
  • Weten hoe
    • Blog
    • Ontmoetingen
    • Webinars
    • Bronnen
Carrière Neem contact op
  • Over ons
  • Diensten
    • Software Ontwikkeling
      • Frontend ontwikkeling
      • Backend ontwikkeling
    • Staff Augmentation
      • Frontend ontwikkelaars
      • Backend ontwikkelaars
      • Gegevensingenieurs
      • Cloud Ingenieurs
      • QA ingenieurs
      • Andere
    • Het advies
      • Audit & Consulting
  • Waarde voor
    • CEO
    • CTO
    • Leveringsmanager
  • Ons team
  • Case Studies
  • Weten hoe
    • Blog
    • Ontmoetingen
    • Webinars
    • Bronnen
Carrière Neem contact op
Pijl terug KEREN TERUG
2019-05-06
Software Ontwikkeling

Objectgeoriënteerd programmeren. Dat is niet hoe je denkt

Pawel Wal

Met de hoeveelheid gratis hulpmiddelen, boeken, online lessen en bootcamps voor codering die nu beschikbaar zijn, kan iedereen leren coderen. Er is echter nog steeds een kwaliteitskloof tussen coderen en software engineering. Moet die er zijn?

Ik schreef mijn eerste "Hello world" meer dan twintig jaar geleden - dat is het antwoord dat ik geef als iemand me vraagt hoe lang ik al coder. De afgelopen tien jaar heb ik genoten van een carrière waarin ik in aanraking kwam met code bijna elke dag - dat is het antwoord dat ik geef als me wordt gevraagd hoe lang ik al professioneel codeur ben.

Hoe lang ben ik al een softwareontwikkelaar? Ik zou zeggen zo'n vijf jaar. Wacht even, deze getallen lijken niet te kloppen! Dus wat is er veranderd? Wie zou ik als software engineer beschouwen en wie "slechts" als programmeur?

De definitie van een software engineer

Coderen is relatief eenvoudig. Het is niet meer allemaal assembly mnemonics op belachelijk beperkte systemen. En als je zoiets expressiefs en krachtigs als Ruby gebruikt, is het nog eenvoudiger.

Je pakt gewoon een kaartje, zoekt waar je je code moet invoegen, zoekt uit welke logica je daar moet plaatsen en boem - klaar. Als je iets geavanceerder bent, zorg je ervoor dat je code mooi is. Logisch is opgedeeld in methodes. Goede specificaties heeft die niet alleen het gelukkige pad testen. Dat is wat een goede codeur doet.

Een software engineer denkt niet meer in methods en classes, althans niet primair. In mijn ervaring denkt een software engineer in flows. Ze zien in de eerste plaats de denderende, razende rivier van data en interactie die door het systeem raast. Ze denken na over wat ze moeten doen om deze stroom om te leiden of te veranderen. Mooie code, logische methodes en goede specificaties komen bijna als bijzaak.

Het zijn helemaal schildpadden

Mensen denken over het algemeen op een bepaalde manier over de meeste interacties met de werkelijkheid. Laten we het bij gebrek aan een betere term het "top-down" perspectief noemen. Als mijn hersenen bezig zijn met het zetten van een kopje thee, zullen ze eerst de algemene stappen bedenken: naar de keuken gaan, de waterkoker opzetten, het kopje klaarmaken, water inschenken, teruggaan naar mijn bureau.

Het zal niet eerst uitzoeken welk kopje ik als eerste moet gebruiken, terwijl ik in slaap val achter mijn bureau; dat in slaap vallen komt later wel, als ik voor de kast sta. Het zal er niet bij stilstaan dat we misschien geen thee meer hebben (of in ieder geval geen goed dingen). Het is breed, reactief en foutgevoelig. Alles bij elkaar - zeer menselijk in de natuur.

Als de software engineer overweegt om wijzigingen aan te brengen in de enigszins verbijsterende gegevensstroom, zal hij dat natuurlijk op een vergelijkbare manier doen. Laten we eens kijken naar dit voorbeeld van een user story:

Een klant bestelt een widget. Bij de prijsbepaling van de bestelling moet rekening worden gehouden met het volgende:

  • Widget basisprijs in de locatie van de gebruiker
  • Widgetvorm (prijsmodificator)
  • Of het een spoedbestelling is (prijswijziger)
  • Of de levering van de bestelling plaatsvindt op een feestdag in de locatie van de gebruiker (prijswijziger)

Dit lijkt misschien allemaal gekunsteld (en dat is het natuurlijk ook), maar het is niet ver verwijderd van enkele echte gebruikersverhalen die ik onlangs heb mogen verpletteren.

Laten we nu eens het denkproces doorlopen dat een software engineer zou kunnen gebruiken om dit aan te pakken:

"We moeten de gebruiker en zijn bestelling krijgen. Dan beginnen we met het berekenen van het totaal. We beginnen bij nul. Dan passen we de widgetvormmodificator toe. Dan de spoedkosten. Dan kijken we of het op een feestdag is, boem, klaar voor de lunch!"

Ah, de kick die een eenvoudig gebruikersverhaal teweeg kan brengen. Maar de software engineer is ook maar een mens, geen perfecte multi-threaded machine, en het recept hierboven is in grote lijnen. De ingenieur moet dan dieper nadenken:

"De widget shape modifier is... oh, dat is super afhankelijk van de widget, nietwaar. En ze kunnen verschillen per locale, zelfs als het niet nu is dan in de toekomst," denken ze, eerder verbrand door veranderende bedrijfsvereisten, "en de spoedkosten kunnen dat ook zijn. En feestdagen zijn ook super plaatsgebonden, augh, en tijdzones zullen een rol spelen! Ik had hier een artikel over het omgaan met tijden in verschillende tijdzones in Rails... ooh, ik vraag me af of de besteltijd wordt opgeslagen met zone in de database! Beter het schema controleren."

Oké, software engineer. Stop. Je wordt verondersteld een kopje thee te zetten, maar je zit in gedachten verzonken voor de kast te bedenken of het bloemige kopje wel van toepassing is op je theeprobleem.

De perfecte kop brouwen widget

Maar dat is gemakkelijk wat er kan gebeuren als je iets probeert te doen dat zo onnatuurlijk is voor het menselijk brein als denken in verschillende dieptes van detail tegelijkertijd.

Na een korte blik in hun ruime arsenaal aan links over het omgaan met tijdzones, vermand onze ingenieur zich en begint hij dit om te zetten in echte code. Als ze de naïeve benadering zouden proberen, zou het er ongeveer zo uitzien:

 def bereken_prijs(gebruiker, order)
   order.prijs = 0
   order.price = WidgetPrices.find_by(widget_type: order.widget.type).price
   order.price = WidgetShapes.find_by(widget_shape: order.widget.shape).modifier
   ...
 einde

En zo gingen ze maar door, op deze heerlijke procedurele manier, om dan bij de eerste code review zwaar te worden afgeslagen. Want als je erover nadenkt, is het heel normaal om op deze manier te denken: eerst grote lijnen en pas veel later details. In het begin dacht je niet eens dat je uit de goede thee was, toch?

Onze technicus is echter goed getraind en niet onbekend met het Service Object, dus dit is wat er in plaats daarvan gaat gebeuren:

klasse BasisOrderService
def zelf.oproep(gebruiker, bestelling)
nieuw(gebruiker, order).aanroepen
einde

def initialiseer(gebruiker, order)
@user = gebruiker
@order = order
einde

def oproep
puts "[WARN] Implementeer niet standaard aanroep voor #{self.class.name}!"
gebruiker, volgorde
einde
einde

Klasse WidgetPriceService < BaseOrderService; einde
Klasse ShapePriceModifier < BaseOrderService; einde
klasse RushPriceModifier < BaseOrderService; einde
klasse HolidayDeliveryPriceModifier < BaseOrderService; einde

klasse OrderPriceCalculator < BaseOrderService
def oproep
gebruiker, order = WidgetPriceService.call(gebruiker, order)
gebruiker, order = ShapePriceModifier.call(gebruiker, order)
gebruiker, bestelling = RushPriceModifier.aanroep(gebruiker, bestelling)
gebruiker, order = HolidayDeliveryPriceModifier.call(gebruiker, order)
gebruiker, bestelling
einde
einde
```

Goed! Nu kunnen we wat goede TDD toepassen, er een testcase voor schrijven en de klassen verder uitwerken totdat alle stukjes op hun plaats vallen. En het wordt nog mooi ook.

En ook volstrekt onmogelijk om over te redeneren.

Vijand is de staat

Natuurlijk, dit zijn allemaal goed gescheiden objecten met afzonderlijke verantwoordelijkheden. Maar hier is het probleem: het zijn nog steeds objecten. Het service object patroon met zijn "doe alsof dit object een functie is" is echt een hulpmiddel. Er is niets dat iemand ervan weerhoudt om HolidayDeliveryPriceModifier.new(user, order).something_else_entirely. Niets weerhoudt mensen ervan om interne status toe te voegen aan deze objecten.

En niet te vergeten gebruiker en bestel zijn ook objecten en ermee knoeien is net zo makkelijk als iemand die stiekem even snel bestellen.opslaan ergens in deze anders "zuivere" functionele objecten, waardoor de onderliggende bron van de staat van de waarheid, a.k.a. een database, verandert. In dit gekunstelde voorbeeld is het geen groot probleem, maar het kan je zeker bijten als dit systeem groeit in complexiteit en zich uitbreidt naar aanvullende, vaak asynchrone, onderdelen.

De ingenieur had het juiste idee. En gebruikte een heel natuurlijke manier om dit idee uit te drukken. Maar weten hoe dit idee uit te drukken - op een mooie en makkelijk te beredeneren manier - werd bijna verhinderd door het onderliggende OOP-paradigma. En als iemand die de sprong nog niet heeft gemaakt om zijn gedachten uit te drukken als omleidingen van de gegevensstroom, probeert om minder vaardig de onderliggende code te wijzigen, zullen er slechte dingen gebeuren.

Functioneel zuiver worden

Was er maar een paradigma waarin het uitdrukken van je ideeën in termen van gegevensstromen niet alleen eenvoudig, maar ook noodzakelijk was. Als redeneren eenvoudig kon worden gemaakt, zonder de mogelijkheid om ongewenste neveneffecten te introduceren. Als gegevens onveranderlijk konden zijn, net als het bloemrijke kopje waar je je thee in zet.

Ja, ik maak natuurlijk een grapje. Dat paradigma bestaat, en het heet functioneel programmeren.

Laten we eens kijken hoe het bovenstaande voorbeeld eruit zou kunnen zien in een persoonlijke favoriet, Elixir.

defmodule WidgetPrijzen doen
def prijsorder([gebruiker, order]) doen
[gebruiker, order]
|> widgetprijs
|> shapepricemodifier
|> spoedprijs-aanpasser
|> vakantieprijsmodificator
einde

defp widgetprijs([gebruiker, order]) doen
%{widget: widget} = order
prijs = WidgetRepo.getbase_price(widget)
[gebruiker, %{order | prijs: prijs }]
einde

defp shapepricemodifier([gebruiker, order]) do
%{widget: widget, prijs: huidige prijs} = order
modifier = WidgetRepo.getshapeprice(widget)
[gebruiker, %{order | prijs: huidigeprijs * modifier} ]
einde

defp rushpricemodifier([gebruiker, order]) doen
%{rush: rush, prijs: huidige prijs} = order
Als rush doen
[gebruiker, %{order | prijs: huidigeprijs * 1.75} ]
anders
[gebruiker, %{bestelling | prijs: huidige_prijs} ]
einde
einde

defp holidaypricemodifier([gebruiker, order]) do
%{datum: datum, prijs: huidige prijs} = order
modifier = HolidayRepo.getholidaymodifier(gebruiker, datum)
[gebruiker, %{order | prijs: huidigeprijs * modifier}]
einde
einde
```

Het zal je misschien opvallen dat het een volledig uitgewerkt voorbeeld is van hoe de user story eigenlijk kan worden bereikt. Dat komt omdat het minder een mond vol is dan het in Ruby zou zijn. We gebruiken een paar belangrijke functies die uniek zijn voor Elixir (maar algemeen beschikbaar in functionele talen):

Zuivere functies. We veranderen de inkomende bestel helemaal niet, we maken gewoon nieuwe kopieën - nieuwe iteraties op de begintoestand. We springen ook niet opzij om iets te veranderen. En zelfs als we dat zouden willen, bestel gewoon een "domme" kaart is, kunnen we niet bestellen.opslaan op geen enkel punt hier, omdat het gewoon niet weet wat dat is.

Patroonmatching. Vergelijkbaar met ES6's destructureren, stelt dit ons in staat om prijs en widget van de bestelling en het doorgeven, in plaats van onze vrienden te dwingen WidgetRepo en VakantieRepo om te weten hoe om te gaan met een volledige bestel.

Pijpexploitant. Gezien in prijsorderHiermee kunnen we gegevens door functies laten lopen in een soort "pijplijn" - een concept dat iedereen meteen kent die ooit ps aux | grep postgres om te controleren of het verdomde ding nog draaide.

Dit is hoe je denkt

Bijwerkingen maken niet echt deel uit van ons denkproces. Nadat je water in je kopje hebt gegoten, maak je je over het algemeen geen zorgen dat een fout in de waterkoker ertoe kan leiden dat deze oververhit raakt en ontploft - in ieder geval niet genoeg om in de binnenkant van de waterkoker te gaan neuzen om te controleren of iemand hem niet per ongeluk heeft achtergelaten. exploderen_na_gieten hoog omgedraaid.

De weg van codeur naar software engineer - voorbij het zorgen maken over objecten en toestanden naar het zorgen maken over datastromen - kan in sommige gevallen jaren duren. Dat deed het zeker voor de OOP-geoefende ondergetekende. Met functionele talen ga je nadenken over flows op je eerste nacht.

We hebben softwareontwikkeling ingewikkeld voor onszelf en elke nieuwkomer op dit gebied. Programmeren hoeft niet moeilijk en hersenkrakend te zijn. Het kan gemakkelijk en natuurlijk zijn.

Laten we dit niet ingewikkeld maken en al functioneel gaan. Want zo denken we.

Lees ook:

  • Waarom versnelt technologie de groei van e-commerce, marktplaatsen en SaaS-bedrijven?
  • Waarom is Ruby on Rails een goede keuze voor softwareontwikkeling? Mijn persoonlijke gedachten

Verwante artikelen

Software Ontwikkeling

Bouw Toekomstbestendige Web Apps: Inzichten van The Codest's Expert Team

Ontdek hoe The Codest uitblinkt in het creëren van schaalbare, interactieve webapplicaties met geavanceerde technologieën, het leveren van naadloze gebruikerservaringen op alle platforms. Ontdek hoe onze expertise digitale transformatie en business...

DE BESTE
Software Ontwikkeling

Top 10 in Letland gevestigde bedrijven voor softwareontwikkeling

Lees meer over de beste softwareontwikkelingsbedrijven van Letland en hun innovatieve oplossingen in ons nieuwste artikel. Ontdek hoe deze technologieleiders uw bedrijf kunnen helpen verbeteren.

thecodest
Oplossingen voor ondernemingen en schaalvergroting

Essentiële Java-softwareontwikkeling: Een gids voor succesvol uitbesteden

Verken deze essentiële gids over succesvolle outsourcing Java-softwareontwikkeling om de efficiëntie te verbeteren, toegang te krijgen tot expertise en projectsucces te stimuleren met The Codest.

thecodest
Software Ontwikkeling

De ultieme gids voor outsourcing in Polen

De sterke groei van outsourcing in Polen wordt gedreven door economische, educatieve en technologische vooruitgang, die IT-groei en een bedrijfsvriendelijk klimaat stimuleert.

DeCodest
Oplossingen voor ondernemingen en schaalvergroting

De complete gids voor IT-auditmiddelen en -technieken

IT-audits zorgen voor veilige, efficiënte en compliant systemen. Lees het volledige artikel om meer te weten te komen over het belang ervan.

The Codest
Jakub Jakubowicz CTO & medeoprichter

Abonneer je op onze kennisbank en blijf op de hoogte van de expertise uit de IT-sector.

    Over ons

    The Codest - Internationaal softwareontwikkelingsbedrijf met technische hubs in Polen.

    Verenigd Koninkrijk - Hoofdkantoor

    • Kantoor 303B, 182-184 High Street North E6 2JA
      Londen, Engeland

    Polen - Lokale technologieknooppunten

    • Fabryczna kantorenpark, Aleja
      Pokoju 18, 31-564 Krakau
    • Hersenambassade, Konstruktorska
      11, 02-673 Warschau, Polen

      The Codest

    • Home
    • Over ons
    • Diensten
    • Case Studies
    • Weten hoe
    • Carrière
    • Woordenboek

      Diensten

    • Het advies
    • Software Ontwikkeling
    • Backend ontwikkeling
    • Frontend ontwikkeling
    • Staff Augmentation
    • Backend ontwikkelaars
    • Cloud Ingenieurs
    • Gegevensingenieurs
    • Andere
    • QA ingenieurs

      Bronnen

    • Feiten en fabels over samenwerken met een externe partner voor softwareontwikkeling
    • Van de VS naar Europa: Waarom Amerikaanse startups besluiten naar Europa te verhuizen
    • Tech Offshore Ontwikkelingshubs Vergelijking: Tech Offshore Europa (Polen), ASEAN (Filippijnen), Eurazië (Turkije)
    • Wat zijn de grootste uitdagingen voor CTO's en CIO's?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Gebruiksvoorwaarden website

    Copyright © 2025 door The Codest. Alle rechten voorbehouden.

    nl_NLDutch
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish etEstonian elGreek nl_NLDutch