Posts

Posts uit december, 2015 tonen

Clean Code - Transformation Priority Premise

De transformation list is als volgt opgebouwd: Null (return null) Null to constant (verander return null naar bij. 2) Constant to Variable (verander bijv 2 naar een variabele) Add computation (maak gebruik van -, +, *, etc.) Split flow (Voeg een if else statement toe, en niet meer dan 2 paden) Variable to Array (maak van een variabele een array) Array to Container (maak van een array een list) If to While (verander de if naar een while loop) Recurse (maak een recursieve methode) Iterate (maak gebruik van een for of een foreach loop) Assign  Add case (Voeg een else if blok toe) Indien er meerdere keuzes zijn om een richting te bepalen, ga dan voor de keuzedie het dichtst bij 1 zit. De kans is waarschijnlijk groter dat dit een betere uitkomst biedt.

Clean Code - Mocking

Tijdens het testen kan het voorkomen dat je nep objecten moet gaan gebruiken. Deze nep objecten komen in verschillende gradaties en vormen een hierarchie. Onderstaand de hierarchie van hoog naar laag. - Test double (= abstract) - Dummy - Een subclass die geen gedrag kent. Alle functies retourneren een waarde die zo dicht mogelijk bij 0 of null ligt. - Stub - De functions voeren geen acties uit en geven fixed waarden terug die de producitecode sturen richting het pad dat getest moet worden - The spy - is hetzelfde als de stub, maar onthoud waarden die bruikbaar zijn voor de test. Zo kan bijvoorbeeld geckeckt worden of er een bepaalde functie is aangeroepen of hoevaak een bepaalde functie is aangeroepen. Deze waarden kunnen dan later weer door de test worden uitgelezen. - The (true) mock - heeft alle eigenschappen die een spy ook heeft. Daar bovenop heeft een mock ook nog een bijzondere feature: hij weet water zou moeten gebeuren. De test checkt niet wat de mock bespioneert. De t

Clean Code - Component Coupling

Stable Dependencies Principle Als van een component meerdere componenten afhankelijk zijn, dan is dit een stabiel component. Een aanpassing op dit component heeft grote gevolgen voor de componenten die er van afhankelijk zijn. Als een component afhankelijk is van alleen maar andere componenten dat is dit een instabiel component. Dit omdat geen andere componenten afhankelijk zijn van dit component. Als je dus code hebt dat veel zal veranderen, plaats deze code dan in een instabiel component. Een stabiel component mag alleen maar afhankelijkheden hebben met andere stabiele componenten. Als een stabiel component afhankelijk is van een instabiel component dan heeft een aanpassing in een instabiel component grote gevolgen op de componentstructuur. De stabiliteit van een component is te berekenen: 1 - Tel het aantal componenten dat afhankelijk zijn van het component (= fan in); 2 - Tel het aantal componenten waarvan het component zelf afhankelijk is (= fan out). Pas deze uitko

Clean Code - Component Cohesion

Wat zit er precies in een component? Uit welke onderdelen bestaat een component? En wat zijn de krachten wat deze onderdelen samenbrengen? De onderdelen zijn de functies. De krachten die deze functies bij elkaar brengen wordt cohesian genoemd. Classes zijn de eerste laag van cohesion voor functies. De enige zichtbare onderdelen van een class zijn de publieke functies. De data van een class wordt altijd verborgen gehouden. Classes zijn een verzameling van functies die allemaal opereren op dezelfde data. Net als functies kunnen classes ook samenhangend (cohesive) zijn. Soms horen classes bij elkaar en soms niet. De kracht van class cohesion bepaald in welk component een class behoort. Het doel van een goede componentstructuur is om ze onafhankelijk van elkaar de deployen. Common Closure Principle Components zijn altijd onderdeel van 1 layer (ui, middleware, data), niet meerdere. In andere woorden, components do'nt cross boundaries. Als een requirement verandert of toegevoeg

Clean Code - Components

Een component is niets anders dan een onafhankelijke deployable library, zoals een dll. Onafhankelijk deployable houdt in dat een verandering in 1 component geen invloed heeft op het compileren en deployen van andere componenten. De voordelen van afhankelijke componenten zijn dat zij onafhankelijk van elkaar kunnen worden deployed, maar ook onafankelijk van elkaar kunnen worden ontwikkeld. Het laatste is erg belangrijk als er gewerkt wordt in teamverband, Bij het ontwerpen van een design is het verstandig om de SOLID principle toe te passen. Als eerste begin je met het Single Responsibility Principle. Dit houdt in dat je gaat bepalen wie de actors zijn. Met andere woorden, welke groepen mensen/gebruikers zullen veranderingen vragen van het systeem. Nadat de actors bekend zijn, worden de namen van de modules bepaald. Een actor representeer een module. De naam van de module is altijd abstract en kent geen details. Voorbeeld: bij de actor die de gaat over de communicatie van het systee

Clean Code - The Dependency Inversion Principle

Stel je voor dat in de main van de applicatie een e-mail wordt verstuurd op het moment er een exception optreed. De functie die deze mail verstuurd ziet er als volgt uit: public class Main() { function OnException(Exception exception) { var mailer = new Mailer(); mailer.SendExceptionMail(exception); } } De class main heeft nu direct een dependency met de class Mailer. Nu komt er een nieuwe requirement en die stelt dat in plaats van een mail er een sms moet worden verstuurd afhankelijk van de ingelogde gebruiker. Dit betekent dus dat Main moet worden aangepast. In andere woorden: Main leunt op implementaties in plaats van abstractions. Wat hier het nadeel van is, is dat bij elke keer dat er een requirement bij komt, Main moet worden aangepast. Beter is om Main te vertellen waar hij het bericht heen moet sturen in plaats dat hij dat zelf uitzoekt: public class Main() { private readonly IExceptionMessenger _exceptionMessenger; public Main (IExceptionMessenger e

Clean Code - The Liskov Substitution Principle

Het LSP heeft te maken met sub classes. Om het Liskov Substitution Principle correct toe te passen moeten alle sub classes vervangen kunnen worden door hun base class zonder dat de aanroepende code hier iets van merkt of aanpassingen hier voor hoeft te doen. Een bekend voorbeeld dat vaak als voorbeeld wordt gebruikt om dit principe toe te lichten gaat over een rechthoek en een vierkant. De rechthoek is de base class en de vierkant de sub class. Omdat de vierkant de base class is, betekent dit dat hij o.a. de methodes SetWidth en SetHeight heeft overgenemen. Maar dit is overbodig voor een vierkant. Voor een vierkant hoeft alleen maar de size te worden opgegeven omdat natuurlijk alle kanten gelijk zijn. De oplossing voor dit stuk is om vierkant niet te laten erven van rechthoek. Het worden dus beide aparte classes, zodat geen trucks hoeven te worden uitgehaald om alles logisch te maken en werkend te krijgen. Hiermee voorkom je dus ook ruis in de code.  Met de volgende checks kun je k

Clean Code - The Interface Segregation Principle

De naam van een interface heeft meer te maken met de gebruiker van die interface dan met de classes die de interface implementeren. Stel je een class Switch voor. Deze class kan bijvoorbeeld een licht bedienen. Aan en uit. Deze communicatie verloopt via een interface. De Switch class mot ook bijvoorbeeld tv's en ventilatoren aan en uit kunnen zetten. Een goede naam voor deze interface zou zijn 'Switchable'. De naam heeft dus meer te maken met de gebruiker van de interface dan met de classes die de interface implementeren. Het probleem dat dit principe oplost is het probleem van fat classes. Dit betekent zeer waarschijnlijk dat er ook veel verschillende componenten gebruik maken van zo'n class. Een wijziging in een fat class heeft zeer waarschijnlijk invloed op één of misschien twee componenten, niet de overige componenten. Om dit op te lossen kan er per component een interface worden geintroduceerd. Vervolgens kunnen al deze interfaces weer worden geimplementeerd door

Clean Code - Open Closed Principle (OCP)

De definitie van het OCP is: gesloten voor aanpassing, maar open voor verandering. Dit betekent dat als er een nieuwe feature komt, de bestaande code niet mag worden aangepast, maar alleen nieuw code wordt toegevoegd. public class Mian() { public string GetInput(input) { if(input == "keyboard") { // do somthing } else if(input == "mouse") { // do somthing } } } Deze code voldoet niet aan het SRP. Als bijvoorbeeld een joystick wordt toegevoegd moet de methode GetInput moet worden aanpast (= bestaande code). Om te voldoen aan het SRP moeten de uitbredibare componenten gescheiden worden door een interface. In dit voorbeeld betekent dit dat er een interface komt 'DeviceInput' en dat er per concreet input apparaat een separate class komt die erft van deze interface: KeyboardInputDevice, MouseInputDevice, etc. Op deze manier kan de joystick worden toegevoegd zonder dat de methode GetInput hoeft te worden aangepast.

Clean Code - Single Responsibility Principle (SRP)

Het SRP gaat er over dat een functie of class maar één ding doet en maar één reden heeft om te veranderen. Bij een class is een verandering afhankelijk van de gebruiker, ook wel actor genoemd. Als er meerdere verschillende gebruikers zijn van een class, betekent dit dat de class meerdere verantwoordelijkheden heeft. Een class is eigenlijk een verzameling van methodes die dezelfde actor dienen. Een class bestaat dus uit een set van methodes die familie van elkaar zijn. Als in een class methodes die niks met elkaar te maken hebben, dan moeten deze gescheiden worden en in een aparte class geplaatst worden.

Clean code

Naamgeving variabelen en functies - Functienamen zijn altijd werkwoorden; - Namen van classes zijn altijd zelfstandige naamwoorde; - Publieke functies hebben hebben kleine namen (die hebben een grote scope); - Private functies mogen lange namen hebben (die hebben een kleine scope); - Variabelen in een kleine scope mogen korte namen hebben; - Variabelen in een grote scope mogen geen korte namen (afkortingen) hebben, grote namen zijn prima; - Variabelen moeten beschrijvend zijn en uitspreekbaar; Functies - Hebben maximaal drie parameters. Meer dan drie parameters kunnen gebundeld worden in een object; - Hebben geen bool als parameter. Als een functie een bool accepteert dan doet hij twee dingen en functies mogen altijd maar één ding doen. Dus mocht een functie een boolean nodig hebben, zijn dit twee functies; - Zijn klein max 4-5 regels; - In grote functies zitten zeer waarschijnlijk een of meerdere classes verborgen; - Functies doen maar 1 ding. Hoe bereik je

Code uitvoeren in Angular nadat de 'ng-repeat' klaar is

Op de volgende manier kun je code uitvoeren, pas als 'ng-repeat' klaar is. Html: thing {{thing}} Javascript: function Ctrl($scope) { $scope.things = [ 'A', 'B', 'C' ]; } angular.module('myApp', []) .directive('myPostRepeatDirective', function() { return function(scope, element, attrs) { if (scope.$last){ // iteration is complete, do whatever post-processing is necessary } }; }); Bron: http://stackoverflow.com/a/13775176/40676

Angular van buitenaf benaderen

Als je werkt met externe applicaties die gebruik maken van Angular en er is geen mogelijkheid om bijv onderdelen te injecteren kan je het volgende gebruiken: angular.element(domElement).scope() // to get the current scope for the element angular.element(domElement).injector() // to get the current app injector angular.element(domElement).controller() // to get a hold of the ng-controller instance. bron:  http://stackoverflow.com/a/10508731/40676

Umbraco know hows

- Een SP kan je in Umbraco uitvoeren met var query = new Sql(";EXEC GetKeywordsByContentId @@contentId = @0", id); var results = DatabaseContext.Database.Fetch (query).ToArray(); - Je kan een Node een eigen link geven door de RoutePath op te geven: node.RoutePath = string.Format("/MyPlugin/MyPluginTree/edit/{0}/{1}", chapterId, node.Id); - Om een custom section als landingpage aan de backend in te stellen, pas je in "/umbraco/Js/routes.js" het volgende aan: .when('/:section', { templateUrl: function (rp) { if (rp.section.toLowerCase() === "default" || rp.section.toLowerCase() === "umbraco" || rp.section === "") { rp.section = "content"; } rp.url = "dashboard.aspx?app=" + rp.section; return 'views/common/dashboard.html'; },