Het organiseren van bedrijfsapplicaties

Organisatie kan de onderhoudbaarheid van een applicatie maken of breken. Bij kleinere applicaties is organisatie duidelijker; Naarmate de applicatie groeit en het aantal applicatieontwikkelaars en front-end engineers die code produceren toeneemt, kan de meer verwarrende organisatie echter worden. In dit bericht bespreken we enkele basisbegrippen voor het georganiseerd houden van applicaties zodat het vinden van relevante code een efficiënt en systematisch proces is.


Leer van Frameworks

JavaScript moet op een efficiënte manier worden geïmplementeerd.

Laten we een moment nemen en nadenken over de manier waarop Rails en WordPress teams hun projecten organiseren. De kans is groot dat je waarschijnlijk met de een of de andere hebt gewerkt. Beide raamwerken hebben een vaste standaardstructuur.

Bij het genereren van een Rails-applicatie, neemt Rails een groot deel van de primaire organisatiebehoeften voor u voor zijn rekening. Omdat het is gebaseerd op MVC, bevat de standaard Rails-installatie een map met het label "app", die model / view / controller-mappen bevat. Het biedt ook de "helpers" en "mailers", de controller-uitbreidingen die helpen de hiaten tussen controllers en modellen in te vullen.

Rails genereert ook een paar andere items op hetzelfde niveau als de map "app", zoals configuratie, logboekregistratie, databases, tijdelijke / caching, tests en enkele andere items. Wat bijzonder interessant is voor deze discussie, zijn de app en openbare mappen. In de openbare map wordt statische inhoud weergegeven, inclusief niet-dynamische HTML-, CSS- en JavaScript-bestanden.

Wanneer u met Wordpress werkt, zijn de naamgeving en structuur veel minder vanzelfsprekend.

... de applicatie is gebouwd voor gebruikers ...

Conventies worden aan de hand van de documentatie uiteengezet. Ontwikkelaars werken met name waarschijnlijk in een thema dat zich in de map wp-content / themes / bevindt. Dit thema heeft een reeks bestanden met speciale namen, voornamelijk op basis van weergaven. EEN functions.php bestand fungeert als een "controller" van soorten, waar een ontwikkelaar functies kan plaatsen om ze te scheiden van de weergaven. Wordpress-thema's modderen echter vaak het water tussen logica en presentatie. Databasequery's zijn bijvoorbeeld impliciet door bestandsnaam, maar worden vaak gemanipuleerd door de query te wijzigen voordat de geretourneerde resultaten worden doorlopen. Deze manipulatie is niet hetzelfde als een controller (en natuurlijk is Wordpress nergens in de buurt van MVC, dus we kunnen dit type organisatie niet verwachten).

Beide frameworks zijn enorm populair en beide gebruiken hun eigen impliciete structurering. Ze vereisen absoluut dat ontwikkelaars begrijpen hoe het systeem werkt om efficiënt te zijn. In onze eigen applicaties moeten we aandacht schenken aan dit organisatorische paradigma en een systematische aanpak creëren voor het structureren van applicaties. Dit speelt zich heel anders af voor elke individuele applicatie.


Een standaard bouwen

De hierboven genoemde frameworks vereisen geen ontwikkelaars om de structuur te definiëren; ze zijn "vooraf bedraad" om op een specifieke manier te werken.

Een belangrijke reden waarom robuuste frameworks deze configuraties vaak abstraheren en standaardstructuren bieden, is zodat mensen een communitystandaard gaan ontwikkelen op basis van de standaardstructuur.

Negeer geen normen bij het organiseren van uw applicatie!

Als u bekend bent met Rails, kunt u hoogstwaarschijnlijk naar een Github-repository kijken en weten of het een Rails-app is, gewoon door de mappenstructuur - Rails heeft een gedocumenteerde standaard.

Negeer geen normen bij het organiseren van uw applicatie! Het is zeer waarschijnlijk dat u, als u een toepassing op bedrijfsniveau organiseert, te maken hebt met modulaire, discrete servicegebaseerde minitoepassingen. Het kan bijvoorbeeld zijn dat u meerdere applicaties hebt gebouwd met een of meer verschillende frameworks, of dat ze met de hand kunnen worden gerold en in combinatie met elkaar werken, waardoor API's worden blootgelegd die de andere services haken. Elk van deze discrete applicaties voldoet waarschijnlijk aan de normen van het framework waarop het is gebouwd; deze standaarden bestaan ​​omdat ze de manier zijn waarop dit raamwerk is ontworpen om te werken. Als u deze normen binnen een afzonderlijke toepassing probeert te wijzigen, komt u waarschijnlijk terecht meer tijd verspillen aan het configureren dan eigenlijk een werkende applicatie bouwen.


Uniformiteit van verbonden onderdelen, uniekheid van afzonderlijke onderdelen

In de praktijk betekent dit dat de dingen die van de ene naar de andere service worden weergegeven, op een uniforme manier moeten werken en dat de onderdelen die intern zijn voor een service, moeten werken op de manier die het beste is voor die specifieke service, waarschijnlijk aangedreven door welk framework of technologiestack waarop de service draait.

Vergeet niet dat de applicatie aan het eind van de dag is gebouwd voor gebruikers en dat gebruikers de scheiding van de discrete services niet kennen of waarderen..

In plaats daarvan begrijpen ze de toepassing en ervaring als één geheel, en dat ene voordeel komt vooral van uniformiteit op het hoogste niveau.

Dus wat moet uniform zijn?

routes

naarmate de applicatie groeit ... kan de meer verwarrende organisatie worden.

Routes (URL-structuren) zijn een van de belangrijkste bepalende factoren voor de werking van een webtoepassing. Het is belangrijk dat uw routes een uniforme structuur hebben. Bijvoorbeeld bij het weergeven van een "gebruikersaccount" met een URL zoals / User / 5 waar 5 is de integer-ID van de primaire sleutel van de gebruiker, gebruik geen meervoud voor een ander enkelvoudig object, zoals / Widgets / 16. In plaats daarvan zou het moeten zijn / Widget / 16. Dit helpt ontwikkelaars niet alleen door consistent te zijn, maar biedt ook duidelijkheid en uniformiteit voor gebruikers. Het maakt niet uit wat u kiest voor uw routestructuur zolang deze consistent is op het niveau van de gebruiker.

API-syntaxis

Dit is er een die uiterst belangrijk is voor interne ontwikkeling, en het is zelfs nog belangrijker voor de ontwikkeling van softwareproducten / -services waar een API aan het publiek wordt blootgesteld. Als uw API-aanroepen onderstrepingstekens hebben als woordscheidingstekens, gebruik dan geen camelCase- of door streepjes gescheiden sleutel in uw API ergens anders. Als u het woord "tellen" gebruikt om te betekenen "dit aantal objecten retourneren", gebruik dan niet iets als "count_per_page" om hetzelfde te betekenen ergens anders in dezelfde (of een gerelateerde) API. Dit is slordig API-ontwerp. Ontwikkel een standaardsyntaxis en blijf erbij; merk op dat dit vaak wordt afgehandeld door goed uitgevoerd routeontwerp in REST-API's.

Zelfstandige naamwoorden, werkwoorden en labels

Over het algemeen moet u bij het werken met "foo-widgets" (willekeurige objecten of acties) in uw toepassing dezelfde terminologie gebruiken voor al uw toepassingen. Hoewel het bijvoorbeeld gebruikelijk is in Rails om de "openbare" directory te gebruiken, hebt u controle over wat erin gaat.

Gebruik geen "js" -map voor één raamwerk en een map "scripts" voor een ander kader.

Noem datamodellen geen "oranje_items" in één kader en "OrangeItems" in een ander kader, tenzij de taal of het kader dit expliciet vraagt ​​om een ​​functionele reden. Zorg er dan ook voor dat er een consistent systeem en een 'grammatica' is en zorg ervoor dat de verschillen tussen de afzonderlijke services zijn goed gedocumenteerd en gerechtvaardigd. Dit soort aanwijzingen en uniformiteit zullen het begrip van classificaties van objecten in een applicatie enorm helpen.

Spiegel routes, mappen en statische bestanden

Spiegelen van routes naar mappen en bestanden helpt enorm om een ​​applicatie georganiseerd te houden. U kunt bijvoorbeeld mappen voor CSS, JavaScript en afbeeldingen in uw "openbare" of "statische" mappen hebben. Als u een structuur van mappen maakt die u toewijst aan uw routes, weergaven, controllers of andere vergelijkbare structuren, kunt u uw CSS modulair houden. U kunt vervolgens een tool zoals CodeKit gebruiken om deze bestanden samen te voegen tot een enkel geminimaliseerd bestand. Natuurlijk heeft u misschien ook een global.css voor regels die van toepassing zijn op de hele applicatie. Zie hieronder voor een voorbeeld (.rb is voor Ruby, maar dit zou kunnen gaan voor elke kaderorganisatie van MVC).

- root / - app / --- modellen / ---- foo.rb ---- bar.rb ---- baz / ----- widget.rb --- views / ---- global. html.erb ---- foo.html.erb ---- bar.html.erb ---- baz / ----- widget.html.erb --- controllers ---- foo.rb - - bar.rb - public - CSS --- global.css --- foo.css --- bar.css --- baz / ---- widget.css - JS --- global.js - - foo.js --- bar.js --- baz / ---- widget.js - Afbeeldingen / --- global / ---- image.jpeg --- foo ---- image.jpeg --- bar ---- image.jpeg --- baz / ---- widget / ----- image.jpeg

Men kan snel zien dat het niet moeilijk zou zijn om specifieke CSS, JavaScript, modellen, enz. Te vinden voor een specifiek gedeelte van de applicatie.

Routes (URL-structuren) zijn een van de belangrijkste bepalende factoren voor de werking van een webtoepassing.

De beste manier om dit te bedenken is om uw bestanden te scheiden in 'delen' van uw site. Bijvoorbeeld, misschien heb je een applicatie die een "admin" -gebied en een "profiel" -gebied bevat. Je zou een kunnen maken global.css bestand om de objecten / regels vast te houden die van toepassing zijn op beide gebieden (inclusief een reset, sommige typografieregels, kleuren, enz.) en maak vervolgens specifieke bestanden die van toepassing zijn op de afzonderlijke gebieden voor regels voor inhoudsjablonen die niet worden gedeeld. Op deze manier blijven ontwikkelaars op een specifieke pagina werken en blijven ze in één of twee bestanden en weten ze precies waar ze de juiste bestanden kunnen vinden.

... of benoem uw statische bestanden naar hun functie

Een andere effectieve manier om uw statische bestanden te beheren, is door ze een naam te geven op basis van wat ze doen. Maak bijvoorbeeld een reset.css, een typography.css, een dimensions.css, een colors.css, etc. Er zijn voor- en nadelen aan deze methode, met name voor CSS. Het houdt je CSS gericht op presentatieregels; het zal echter waarschijnlijk vereisen dat u selectors herhaalt over meerdere bestanden, en ze opnieuw opent om verschillende soorten stijlregels te definiëren. De enige manier om dit te voorkomen, is door uw klassen / ID's alleen op stijl te noemen in plaats van op semantiek, zoals class = "green-text five-columns medium-shadow". Anders zul je als volgt iets doen:

In typography.css

.semantische widget color: # 232323; text-shadow: 1px 1px #fff; lettergrootte: 1.2em; regelhoogte: 1.1em; font-family: sans-serif; font-gewicht: 300; 

In dimensions.css

.semantische widget breedte: 20%; marge: 0 2,5%; opvulling: 10px; 

Wat natuurlijk niet zo droog mogelijk is.

De organisatie van kleinere applicaties (met minder van deze "widget" -objecten) kan nog steeds profiteren van het scheidingstype per regel.

Als u echter een toepassing hebt met veel verschillende objecttypen, toepassingsgebieden, enzovoort, moet u er waarschijnlijk voor kiezen om uw CSS-bestanden te scheiden in gebieden (de spiegelingsstrategie die we hierboven hebben besproken).

Het benoemen van JavaScript-bestanden op basis van hun functies is iets meer haalbaar, maar alleen als u misbruik maakt van gebeurtenistriggers (een pub / submodel). Bekijk het volgende voorbeeld:

$ .getJSON ("/ messages / all.json", functie (gegevens) // wat dingen doen);

Misschien wilt u nogal wat dingen doen in deze callback. Mogelijk wilt u een melding naar de gebruiker verzenden en een lijst met berichten bijwerken. Als u uw bestanden hebt gescheiden door functionaliteit, heeft u mogelijk een notifications.js en een messages.js bestand dat deze specifieke functies verwerkt. Binnen de callback voor deze JSON ajax-aanroep zou u een gebeurtenis "publiceren" naar de rest van de toepassing. Vervolgens kunt u zich binnen uw berichten- en berichtenbestanden 'abonneren' op de gebeurtenis en dienovereenkomstig reageren.

in events.js:

$ .getJSON ("/ messages / all.json", functie (berichten) $ ("body"). trigger ("received_messages", berichten););

in messages.js:

$ ("body"). on ("received_messages", functie (event, berichten) // itereren door berichten en toevoegen aan een lijst);

in notifications.js

$ ("body"). on ("received_messages", functie (gebeurtenis, berichten) // send_notification kan een lokale functie zijn waarmee u meldingen // naar de gebruiker kunt verzenden, samen met een meldingstype, een geheel getal; In dit geval kan "1" bijvoorbeeld eenvoudigweg betekenen dat de melding wordt aangemerkt als een "succes" -signaal send_notification ("Succesfully Received Messages!", 1););

Nog een opmerking over statische bestanden

Er zijn een paar dingen die u in gedachten moet houden over uw statische bestanden. In dit artikel wordt ervan uitgegaan dat u uw statische bestanden op de juiste manier aaneenschakelt. Maar wat is precies geschikt?

Overweeg sitecomplexiteit

Chris Coyier onlangs beweerde dat geen enkele applicatie meer dan drie CSS-bestanden nodig heeft. In een gedestilleerd formaat beweert hij dat de meeste sites die één pagina hebben, of veel pagina's die erg op elkaar lijken, één CSS-bestand nodig hebben. Toepassingen met verschillende "siled" secties hebben één CSS-bestand nodig voor globale elementen en één bestand voor de specifieke secties. Ten slotte hebben zeer complexe sites drie bestanden nodig (globale, deelspecifieke en eenmalige pagina css). Chris verwijst naar bestanden die in het hoofd zijn geladen (niet noodzakelijk wat je ontwikkelt), dus dit zijn je aaneengeschakelde bestanden.

Dus waarom zou je dit doen, vraag je? In de eerste plaats om te profiteren van de browsercache.

Samenvoegen tijdens het spelen staat je bijvoorbeeld niet toe om te profiteren van de cache van de browser. Het andere voordeel van deze aanpak is alleen laden wat u nodig hebt. Als u een volledige "admin" -sectie heeft die 95% van uw gebruikers nooit te zien krijgt, hoeven ze de CSS voor die sectie niet te downloaden.

Ontwikkel een standaardsyntaxis en houd u eraan.

Net als bij CSS, moet JavaScript op een efficiënte manier worden gebruikt.

De winsten moeten altijd zorgvuldig worden beheerd; als je javascript klein genoeg is om aaneenschakeling tot een enkel script te rechtvaardigen, voel je dan niet onder druk om gemodificeerd JavaScript in je eindproduct te laden.

Overweeg het gebruiksvolume

Zoals hierboven kort gezegd, als er een verwaarloosbaar aantal gebruikers is dat een specifieke pagina raakt, plaats de CSS / JS dan niet in de statische bestanden van uw globale applicatie. Administratieve statische bestanden moeten ook gescheiden blijven. Als uw toepassing gebruikersaccounts ondersteunt, overweeg dan om de statische bestanden voor de ongeoorloofde (marketing) kant van de toepassing te verwijderen. Zodra een gebruiker zich aanmeldt, hebben ze al een toezegging gedaan om deel te nemen aan wat uw toepassing ook biedt. Eerste indrukken zijn alles, en het laden van een hoop ongebruikte CSS en JavaScript zal de prestaties van een eerste indruk alleen maar verslechteren.


Wat zou uniek moeten zijn?

Als u inderdaad een framework gebruikt, gebruik dan de bestaande structuur van dat framework. Als uw framework geen bestaande structuur heeft, of een zeer eenvoudige structuur (Sinatra en CodeIgniter zijn hier uitstekende voorbeelden van), overweeg dan om de structuur van andere componenten in de applicatie te spiegelen. Als u helemaal opnieuw begint, bekijk dan andere projecten die mensen hebben voltooid in zowel het kader dat u gebruikt als in andere kaders die dezelfde taal gebruiken. Bijvoorbeeld, als je gekozen framework werkt op MVC maar geen standaardconfiguraties heeft voor de plaatsing van deze stukken, is het waarschijnlijk dat er een naamgeving is conventie die de trefwoorden Model, Weergave en Controller gebruikt.

Als het er op aan komt, is organisatie op bedrijfsniveau ongeveer vier belangrijke dingen:

  1. Wees consistent; interne, toepassingsbrede conventies ontwikkelen.
  2. Volg framework / community-conventies waar mogelijk en indien nodig.
  3. Maak een logische, zelfdocumenterende keuze
  4. Documenteer uw keuzes en zorg ervoor dat inconsistenties binnen het systeem of met conventies zichtbaar zijn voor iedereen die aan de software werkt.