[Alg] Principles of Software Development

Pagina: 1
Acties:

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Ik kwam net dit artikel tegen.

Het gaat hier om een aantal 'principes' die een (enterprise) developer zou moeten hanteren bij het ontwikkelen van software.
Sommige mensen zullen deze principes wel al kennen en hanteren, anderen niet.
Zelf ben ik het eens met de auteur: unit testing, ontwikkelen in layers, rekening houden met veranderingen en je code zo aanpasbaar/uitbreidbaar mogelijk maken is noodzakelijk.
Daarom denk ik wel dat het interessant is om een linkje naar dat artikel te posten. :P

https://fgheysels.github.io/


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik ben het niet eens dat je code zo aanpasbaar/uitbreidbaar mogelijk moet maken. Wel vind ik dat je varaties al snel moet uitzoeken en zo moet designen dat je hierop gemakkelijk kunt uitbereiden. En verwachte veranderingen die niet direct toepasbaar zijn moet je je natuurlijk ook op voorbereiden. Maar je moet wel coden naar de eisen die nu worden gesteld. Generalizeren tot in het oneindige is tijdverspilling en helpt je niet veel verder. Als je je aan de normale princiepes houdt is je code dan ook gemakkelijk te refactoren naar een oplossing die verandering wel toelaat. Of bedoelde je dat met het zo aanpasbaar/uitbreidbaar mogelijk maken?

Noushka's Magnificent Dream | Unity


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Beetje raar artikel. Op het eerste gezicht zijn het nogal triviale principes, maar de toelichting erbij is nogal onlogisch en door de eenzijdige benadering alleen interessant voor ASP.NET programmeurs.

Ik vind ook de titels van sommige principes nogal nietszeggend ("You Are What You Eat?!") en de tekst is soms nogal onsamenhangend. Bij principe 1, "Keep It Simple", steekt de auteur bijvoorbeeld een verhaal af over unit testing. Dat heeft er volgens mij niets mee te maken.

Verder schiet de auteur in zijn betoog voor decoupling veel te ver door, door te suggeren dat de klasse van te instantieren objecten niet in code moet staan, maar via een factory method geinstantieerd moeten worden, zodat je de klasse in een configuratie-bestand kunt opgeven. 8)7 Zoals een andere lezer ook al opmerkte staat dat haaks op de principes achter een statisch getypeerde taal als C#: "No compile checking anymore. We can just as wel go back to VB6 that way!".

Al met al komt het artikel op mij over als een samenraapsel van ideeën en ervaringen van de auteur. Niet slecht, maar zeker geen samenvatting van de "principes van software ontwerp".

[ Voor 8% gewijzigd door Soultaker op 21-12-2004 17:22 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Michali schreef op dinsdag 21 december 2004 @ 17:01:
Ik ben het niet eens dat je code zo aanpasbaar/uitbreidbaar mogelijk moet maken.
Zo uitbreidbaar en aanpasbaar als nodig is maar niet meer ;) Ik hou zelf ook van een zo clean mogelijk ontwerp zonder allerlei... dit kan ooit wel eens handig zijn.. zaken.
Wel vind ik dat je varaties al snel moet uitzoeken en zo moet designen dat je hierop gemakkelijk kunt uitbereiden. En verwachte veranderingen die niet direct toepasbaar zijn moet je je natuurlijk ook op voorbereiden. Maar je moet wel coden naar de eisen die nu worden gesteld. Generalizeren tot in het oneindige is tijdverspilling en helpt je niet veel verder.
pcies.
Als je je aan de normale princiepes houdt is je code dan ook gemakkelijk te refactoren naar een oplossing die verandering wel toelaat. Of bedoelde je dat met het zo aanpasbaar/uitbreidbaar mogelijk maken?
Dat is wel mijn gok :)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Soultaker schreef op dinsdag 21 december 2004 @ 17:04:
Verder schiet de auteur in zijn betoog voor decoupling veel te ver door, door te suggeren dat objecten niet at runtime geinstantieerd moeten worden maar dynamisch geladen moeten worden, zodat je de klasse in een configuratie-bestand kunt opgeven. 8)7 Zoals een andere lezer ook al opmerkte staat dat haaks op de principes achter een statisch getypeerde taal als C#: "No compile checking anymore. We can just as wel go back to VB6 that way!".
Uhh.. dit snap ik niet helemaal. Het is in .NET onmogelijk om een verkeerd type object ergens in te gebruiken. Ik denk dat hij bedoelt dependency injection (dus een concrete implementatie van een bepaald interface pas runtime te kiezen. Dat doe ik ook vaak omdat je goeie ontkoppeling krijgt van systemen en daardoor oa fijn kunt unit testen.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Alarmnummer schreef op dinsdag 21 december 2004 @ 17:18:
Uhh.. dit snap ik niet helemaal. Het is in .NET onmogelijk om een verkeerd type object ergens in te gebruiken. Ik denk dat hij bedoelt dependency injection (dus een concrete implementatie van een bepaald interface pas runtime te kiezen. Dat doe ik ook vaak omdat je goeie ontkoppeling krijgt van systemen en daardoor oa fijn kunt unit testen.
Ik had het wat onhandig geformuleerd. Het ging er om dat hij ter illustratie van het principe "Allow For Extension" een manier beschreef om klassen te specificeren in een configuratiebestand, zodat object via een factory method konden worden geinstantieerd en die factory method dan ook dynamisch code kon laden.

Dat is naar mijn mening een verkeerde idee van uitbreidbaarheid handhaven. Het is idioot (en misschien een security risk) om de gebruiker te laten beslissen welke klassen gebruikt worden. Dat is programmacode. De auteur lijkt te willen bereiken dat je voor het uitbreiden van het programma de programmacode niet opnieuw hoeft te compileren. Dat is in veel gevallen gewoon onzinnig; je moet niet de programmacode verplaatsen naar een configuratiebestand.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Soultaker schreef op dinsdag 21 december 2004 @ 17:25:
[...]

Dat is naar mijn mening een verkeerde idee van uitbreidbaarheid handhaven. Het is idioot (en misschien een security risk) om de gebruiker te laten beslissen welke klassen gebruikt worden. Dat is programmacode. De auteur lijkt te willen bereiken dat je voor het uitbreiden van het programma de programmacode niet opnieuw hoeft te compileren. Dat is in veel gevallen gewoon onzinnig; je moet niet de programmacode verplaatsen naar een configuratiebestand.
Het is idd een risico, maar je kan het risico wel inperken, door er bv voor te zorgen dat die class van een bepaalde base class of interface moet inheriten.

Het is dan ook een heikel punt dat je niet zomaar moet toepassen. (Ik heb het wel in een project gedaan. :P)

[ Voor 8% gewijzigd door whoami op 21-12-2004 17:34 ]

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Soultaker schreef op dinsdag 21 december 2004 @ 17:25:
Dat is naar mijn mening een verkeerde idee van uitbreidbaarheid handhaven. Het is idioot (en misschien een security risk) om de gebruiker te laten beslissen welke klassen gebruikt worden.
De gebruiker laten bepalen welke implementatie gebruikt wordt is idd onzin. Maar ik vind het zelf wel vrij prettig om in grote lijnen mijn hele applicatie in elkaar te laten lijmen door een container. Ik heb 1 centraal object in mijn hele systeem die verantwoordelijk is voor alles wat te maken heeft met object initialisatie/destructie en welke concrete implementaties een bepaalde class meekrijgt in zijn constructor. Ik vind dit een erg overzichtelijk geheel geven doordat je dat aspect van je systeem hebt gecentraliseerd. Ik gebruik voor deze container trouwens Spring en die kan nog veel meer dan alleen wat objecten aanmaken. Maar ik neem aan dat je bekend bent met het begrip Inversion of Control en Dependency Injection?

[ Voor 3% gewijzigd door Alarmnummer op 21-12-2004 17:42 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

whoami schreef op dinsdag 21 december 2004 @ 17:30:
[...]
Het is idd een risico, maar je kan het risico wel inperken, door er bv voor te zorgen dat die class van een bepaalde base class of interface moet inheriten.
Volgens mij is het zelfs totaal onmogelijk dat je een verkeerde class gebruikt (dus een class die niet van een bepaalde class/interface extend).

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Alarmnummer schreef op dinsdag 21 december 2004 @ 17:39:
Maar ik neem aan dat je bekend bent met het begrip Inversion of Control en Dependency Injection?
In grote lijnen wel, maar daarbij maak je 'gewoon' gebruik van polymorfie en wat factory methods. Die kun je heel nuttig gebruiken om decoupling te realiseren en om de keuze van klassen los te koppelen van de plek waar ze daadwerkelijk geinstantieerd worden. Als je voor datzelfde doel teruggrijpt naar de dynamic loading/reflection ondersteuning van het platform (zoals de auteur van het artikel doet) heb je naar mijn mening het punt niet echt begrepen.

Het gaat mij er om dat je niet afhankelijk moet zijn van de mogelijkheid om programmacode in lexicale vorm (een stringrepresentatie van een klassenaam bijvoorbeeld) te kunnen uitvoeren. Dan kun je een eval() functie in scripttalen als PHP ook wel aanprijzen als een goede constructie om code uitbreidbaar te maken, want je kan het argument invullen hoe je maar wil.

Reflection en dynamic loading hebben zeker hun nut, maar voor een aantal welgedefinieerde gevallen waarin er simpelweg geen alternatief is (ze hebben dus een duidelijke meerwaarde; het is geen syntactische toevoeging ofzoiets). Als je die technieken gebruikt om problemen op te lossen die ook met eenvoudigere mechanismen goed op te lossen zijn, dan schiet ofwel de programmeertaal of de programmeur tekort.

[ Voor 38% gewijzigd door Soultaker op 21-12-2004 17:54 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Soultaker schreef op dinsdag 21 december 2004 @ 17:49:
[...]

In grote lijnen wel, maar daarbij maak je 'gewoon' gebruik van polymorfie en wat factory methods. Die kun je heel nuttig gebruiken om decoupling te realiseren en om de keuze van klassen los te koppelen van de plek waar ze daadwerkelijk geinstantieerd worden. Als je voor datzelfde doel teruggrijpt naar de dynamic loading/reflection ondersteuning van het platform (zoals de auteur van het artikel doet) heb je naar mijn mening het punt niet echt begrepen.
Dan moet je een stempel op je voorhoofd krijgen: ongeschikt
Het gaat mij er om dat je niet afhankelijk moet zijn van de mogelijkheid om programmacode in lexicale vorm (een stringrepresentatie van een klassenaam bijvoorbeeld) te kunnen uitvoeren. Dan kun je een eval() functie in scripttalen als PHP ook wel aanprijzen als een goede constructie om code uitbreidbaar te maken, want je kan het argument invullen hoe je maar wil.
Klinkt als iets dat je niet graag in je systeem wilt.
Reflection en dynamic loading hebben zeker hun nut, maar voor een aantal welgedefinieerde gevallen waarin er simpelweg geen alternatief is (ze hebben dus een duidelijke meerwaarde; het is geen syntactische toevoeging ofzoiets). Als je die technieken gebruikt om problemen op te lossen die ook met eenvoudigere mechanismen goed op te lossen zijn, dan schiet ofwel de programmeertaal of de programmeur tekort.
Idd.. in 99% van de gevallen is reflection een barslechte oplossing. Maar met dynamic classloading heb ik veel minder problemen (mits het gecontroleerd gebeurd).

Verwijderd

Grappig. Toen ik de reacties las dacht ik al meteen dat het wel verdacht veel leek op Better, Faster, Lighter Java, en inderdaad :) Ik ben dat boek nu zelf aan het lezen, en er staan wel leuk dingen in, maar ook wel wat zaken die te overdreven zijn. Een van de andere dingen waar ik het niet mee eens ben is dat je eigenlijk totaal niet met behulp van diagrammen moet designen. Nu moet je dat zeker niet teveel doen en moet je ook zeker wel het alternatief van de auteur toepassen (refactoren met unit tests als safety net), maar helemaal 0.0% design met diagrammen?

Overigens, de quote van alarmnummer komt ook dat boek ;)

Verwijderd

Om te beginnen wil ik zeggen dat ik het artikel nogal matig vind. Ik hoop dat het boek beter is.

Laat ik eens heerlijk kort door de bocht gaan en proberen de principes in één zin op te sommen (ja; dit is behoorlijk ongenuanceerd, maar het is in elk geval wel duidelijk. Corrigeer me alsjeblieft als ik de plank missla bij de samenvatting van een sectie.). Daarna zal ik er mijn [als altijd nederige] mening over geven.

Principe 1: Schrijf code die precies doet wat nodig is en niets meer, refactoren kan later altijd nog.
Voorbeeld: Gebruik van unit tests

Dit is natuurlijk hèt credo van het Extreem Programmerende volk. Ik heb er persoonlijk nooit veel aan gedaan dus ik kan er geen waardeoordeel over vellen. Ik kan me wel voorstellen dat het in een grootschalig project met een lange levensduur een nuttig stuk gereedschap kan zijn.

Verder vind ik het voorbeeld niet echt veel aan het principe illustreren; het laat alleen zien dát je kan unit testen met een bestaand framework. Ja woepie, als we overtuigd waren geweest van het nut van unit tests dan hadden we daar zelf ook wel iets voor kunnen schrijven.

Principe 2: Separation of concerns is goed!
Voorbeeld: Scheiding van `business-' en presentatielogica in een webscript.

Dit is natuurlijk iets wat we met de paplepel ingegoten krijgen als informaticastudenten, en wat anders in de praktijk met schade en schande wel geleerd wordt. En zoniet, dan wordt het wel aan iedere PHP hacker verteld die op GoT een vraag komt stellen.

Een beetje intrappen van een open deur, maar goed, het kan blijkbaar niet vaak genoeg gezegd worden.

Principe 3: Separation of concerns is goed!
Voorbeeld: Scheiding van domain logic en persistentielogica.

Misschien ligt het aan mij, maar ik zie niet echt het verschil in boodschap tussen dit en het vorige principe; er wordt alleen een ander voorbeeld gegeven.

Oh, en dat separation of concerns goed was wisten we natuurlijk al.

Principe 4: Je bent zelf verantwoordelijk voor libraries die je van het internet af plukt.
Voorbeeld: Een opsomming van libraries die van Java naar .NET geport worden

Gôh. En ik maar denken dat ik door het gebruik van een library de makers zou kunnen verplichten met mij mee te coden en te bugfixen.

Sorry. Het gebruik van sarcasme is natuurlijk een teken van zwakte. Maar ik zie eerlijk gezegd niet in waarom dit een `principe van software development' zou moeten zijn.

Een ècht principe zou geweest zijn: `Hergebruik zoveel mogelijk software'. Of het een goed principe is, kan ter discussie staan. Maar blijkbaar vindt de schrijver zo'n principe iets te sterk uitgedrukt, dus zeg hij in plaats daarvan:

`Als je software hergebruikt, dan moet je goed opletten wat voor software je daarvoor uitkiest!'

Als ik ooit een sine qua non gehoord heb...

Principe 5: Schrijf je programma zodat het uitbreidbaar is zonder opnieuw te compilen
Voorbeeld: Instantiëer klassen met een factory in plaats van direct (en daarbovenop: lees de te instantiëren klassen uit een configuratiefile!)

Bij deze samenvatting heb ik een beetje op mijn tenen moeten staan, omdat het voorbeeld het grootste deel van de sectie in beslag neemt; maar ik neem aan dat de schrijver zoiets heeft bedoeld. Of misschien ook niet; hoewel de eerste paar regels over een meer algemeen soort uitbreidbaarheid gaan, neigt het behoorlijk naar out-of-the-box uitbreidbaarheid.

Hoe dan ook; in principe is het geen heel slechte zaak om een systeem af te leveren dat de eindgebruiker (of beter, de applicatiebeheerder van de eindgebruiker) aan kan passen zonder dat deze daarbij een compiler nodig heeft (nog afgezien van het `bezwaar' dat daarvoor de source bijgeleverd moet worden, ieks, daar gaat ons intellectueel eigendom!). Op die manier is het mogelijk om een product aan te passen zodat het beter in een bepaald bedrijf past, of het uit te breiden met eigen of 3rd party functionaliteit.

En laten we wel wezen, reflectie (of introspectie) is gewoon een heel erg makkelijke manier om uitbreidbaarheid en onderhoudbaarheid te realiseren zonder code-duplicatie. Dat wil zeggen, als je iets (een klasse, of methode, of resource, of wat dan ook) op een bepaalde plek in de code beschikbaar maakt, dan kan de rest van het systeem middels introspectie uitvinden wat er precies beschikbaar is; dit scheelt je de moeite om nog extra case analysis uit te voeren op de specifieke gevallen.

En laten we wel wezen, bij het schrijven van een unit test library is introspectie ook best nuttig, en bij een persistentiemanager ook. Zoals je misschien wel kan raden ben ik een behoorlijke fan van introspectiefactiliteiten, omdat ze erg losse koppelingen mogelijk maken. Ik ben het met Soultaker eens dat introspectie niet de essentie van losse koppeling en concern separation is, maar verdomd makkelijk om te hebben is het toch wel.

Zoals ik het zie: het artikel (en volgens extrapolatie, het boek) is een ode aan onderhoudbaarheid van software, met een paar praktische technieken die je daarvoor kunt gebruiken. Tja. Niet heel vernieuwend, maar het kan natuurlijk altijd nuttig zijn voor programmeurs die hun brood verdienen met de behandelde talen.

  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

Mja, behoorlijk wat zaken die we allemaal al hoorden te weten. Bovendien vind ik de focus heel erg liggen op het schrijven/aanpassen van code. Voor ontwikkelaars is dat natuurlijk zo'n beetje de hele wereld, maar in het echt gaat die code ook nog eens een keer ergens draaien in een produktie-omgeving.

Iets wat ik bijvoorbeeld in het artikel mis is het run-time kunnen beinvloeden van je code. In een complexe (server)omgeving wil je bepaalde functionaliteit aan of uit kunnen zetten zonder dat je het hele systeem moet stoppen. Dat houdt ook in dat je je systeem ontwerpt met buffers tussen de verschillende functioneler blokken die al dan niet actief kunnen zijn. Persistente message queues zijn dan onmisbaar.

Java biedt bovendien een standaard oplossing voor het run-time managen van objecten: JMX. Ik ben benieuwd of .Net iets gelijkwaardigs kent.

With the light in our eyes, it's hard to see.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op dinsdag 21 december 2004 @ 20:28:
Overigens, de quote van alarmnummer komt ook dat boek ;)
Yep.. maar ik moet ook eerlijk toegeven dat ik alleen maar vluchtig door het boek heb gebladerd ;)

Verwijderd

Verwijderd schreef op dinsdag 21 december 2004 @ 21:33:

Principe 5: Schrijf je programma zodat het uitbreidbaar is zonder opnieuw te compilen
Voorbeeld: Instantiëer klassen met een factory in plaats van direct (en daarbovenop: lees de te instantiëren klassen uit een configuratiefile!)
is dat niet gewoon het principe van de alom bekende plugin?
en zoiets gebruik je natuurlijk niet om je hele programma dynamisch inelkaar te zetten.
een progje dat aanelkaar hangt van allemaal kleine plugins heeft nogal de neiging om net zo hard weer uit elkaar te vallen.
ook al heb je al je plugins ge-unit-test tot op het bot.

dat effect noemt men "emergent behaviour"

op deze pagina staat een uitleg, maar in de allereerste paragraaf staat ook gelijk het allergrootste nadeel.

zulke systemen hebben namelijk de neiging gedrag te gaan vertonen wat je als progger er niet expliciet hebt ingestopt. tis daarom ook niet voor niks dat het een term is die veel wordt gebruikt in het onderzoek naar AI en AL.

web-browsers zijn een goed voorbeeld. enorm pluggable, maar als je er teveel tegelijk inplugt gaan er altijd wat stuk. (en dan hebben we het nog niet eens over kwaadwillende "plugins")

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Sorry ReSc, maar emergent behaviour is een onderzoeksveld op het gebied van kunstmatige intelligentie en heeft als zodanig heel weinig met software engineering te maken. Een uitbreidbaar systeem heeft geen 'emergent behaviour' want het gedrag komt voor uit expliciet ontworpen modules (ook al kun je die in pluggen in een bestaand systeem). Emergent behaviour is juist gedrag dat niet expliciet geprogrammeerd is.

Verwijderd

Verwijderd schreef op woensdag 22 december 2004 @ 19:22:
is dat niet gewoon het principe van de alom bekende plugin?
en zoiets gebruik je natuurlijk niet om je hele programma dynamisch inelkaar te zetten.
een progje dat aanelkaar hangt van allemaal kleine plugins heeft nogal de neiging om net zo hard weer uit elkaar te vallen.
Nee hoor, dit hoeft helemaal niet zo te zijn. Neem nou bijvoorbeeld Eclipse, dat is 1 en al plug-ins. De meeste mensen kennen het alleen als een Java IDE, maar zelfs dat gedeelte is een plug-in (JDT). Eclipse is zelf eigenlijk alleen een kleine core waarin werkelijk alles wat je ziet of bedenkt een plug-in is. Je zou er net zo goed een tekst verwerker mee kunnen opbouwen, of een hele office suit (en dat wordt dan ook de target van het zogenaamde Rich Client Platform).

Toch valt Eclipse zeer zeker niet uitelkaar.
Pagina: 1