Jeg elsker både VB.NET og C#, hvilken skal jeg så vælge?

by Jesper Blad Jensen aka. Deldy 18. January 2010 16:46

Jeg er lidt i et dilema. Jeg elsker både VB.NET og C#.

Når jeg skal lave et nyt projekt, så sidder jeg altid og bruger alt for lang tid på at spekulere i hvilket sprog, jeg skal lave mit program i. Vi er alle enige om at det på et højt plan er rimelig ligegyldigt, da VB.NET og C# på et feature plan, er så ens, at der næsten ikke er forskelle - og dog.

Jeg elsker mit VB.NET, jeg er ikke flov over at sige det, selvom jeg godt ved at C# programøres generalisering af en VB.NET programmør, er at han er en anden-rangs programmør, som ikke har lært sine simikolons, og skriver dårlig kode. 

Så lad mig som det første slå det fast: Jo jeg skriver dårlig kode - men det gør jeg også i C# - sproget har intet med det at gøre Smile

Hvis jeg kigger på sprogene side om side, så har jeg meget svært ved at argumentere for at bruge C#, andet end den Geek love der følger med. Hvis jeg laver et VB.NET projekt, så er jeg noget mere alene, end hvis jeg f.eks. lavede det i C#. Jeg kan lige forestille mig den ”addr” føelse, som C# programmørene får, når de finder ud af at projektet er VB.NET.

Men sådan er .NET kulturen, og det er nok ikke noget man kan gøre noget ved.

Grunden til at jeg er så glad for VB.NET er at jeg ser C# som et meget kræsent sprog. Et eksempel er at du skal Caste dine objekter til strings eller til andre sjove objekter, hvilket resultere i en masse tekst, for at fortælle compileren, at du ved hvad du gør. I VB.NET stoler compileren på dig, som standard, og lader dig caste ting til andre typer, uden at du skal til at caste. Du har også muligheden for at sætte såkaldt Strict på, hvilket betyder at den nu også hyler, når du gør den mindste ting, som kunne resultere i fejl, som er sket ved casting. Du har altså valget.

Nu skal det siges, at jeg har oplevet, at vi har fået en enkelt fejl, i forbindelse med implicit casting i VB.NET, i det år, jeg har arbejdet med VB.NET på arbejdet. Hvis man tager den tid, det tog at finde den fejl (10min), og så opvejer det med den tid jeg har sparet, ved ikke at skulle caste hele tiden, så tror jeg nok jeg har vundet nogle dage på den der. Casting er en produktivitets dræber – puntum.

VB.NET har også en masse fede features, som XML literals, og My namespacet, som er fyldt med goodies. Vi har With keywordet, som gør at vi kan tilgå et objekt nemt, hvis vi bruger det mange gange. Select Case (switch) er faktisk brugbart i VB.Net, hvor i C# er den meget mere begrænset. En anden ting, som er lidt sjov i forbindelse med extensionmethods er at VB.Net også har noget som heder Modules. Modules, giver dig lige præcis mulighed for at have extenionmethods, som du kan kalde, uden at de ligger på et objekt, da de bare er globale metoder, alt efter hvilket namespace du inkludere. Derfor kan du lave små metoder, som gør din kode mere præcis – pas dog på med at du lige pludselig ikke gør din kode ikke-testbar. (Det samme gælder med extenionmetodes, og generelt statiske ting)

Modules er dog ikke noget, som jeg generelt bruger så meget, men det er en sjov lille ting i VB.NET, som kan have sin plads, og måske erstatte den typiske Utils klasse, med hjælpemetoder.

Generelt, vil jeg faktisk beskrive VB.NET, som mere Ruby agtigt, end C#. Det giver nogle fede features, som er koblet op mod produktivitet, istedet for ”korrekthed”.

Grunden til jeg elsker C# er dog lidt anderledes. Det er nemlig ikke pga. sproget, men mere de tools, som understøtter det. Resharper er et godt eksempel, som ganske hvist også virker 10% til VB.NET, men det er bare så meget bedre i C#. 

Kodeeksempler er generelt også i C# - så man skal til at konvere koden til VB.NET – hvilket er ganske let, men dog en irretation aligevel.

Til sidst, så er det, lige som med meget andet, bare så meget lettere at følge med strømmen, og bruge det som alle hylder – så slipper man for alle diskutionerne om hvorfor man dog ikke brugte C#.

Jeg er stadig i tvilv om hvad jeg skal bruge, men sådan er det med valg – jeg er bare dårlig til sådan noget. 

 

Nå men, hvad siger jakob?

Tags:

T4MVC: Strongly typed resourcer, helpers osv. til ASP.NET MVC

by Jesper Blad Jensen aka. Deldy 9. November 2009 17:57

Jeg var til et Microsoft event her i lørdags hvor vi hørte Scott Hanselman snakke om ASP.NET MVC. Det meste af det han snakkede var noget jeg kendte i forvejen, men han viste en rigtig fed ting, som de har lavet til MVC.

Scott viste en T4 template, som du bare river ind i dit MVC projekt. Denne T4 template går så ind og kigger på dit projekt, og laver statiske klasser til alle dine billeder, views, controllers osv. På denne måde får du “semi-strongly-typed” links til filer, views osv.

Hvis du f.eks. fjerne eller omdøber en image fil i dit projekt, vil T4 templaten omdøbe det statiske felt, og du vil på den måde ikke kunne kompile – det er da genialt.

Scott viste kun ganske hurtigt hvad denne T4 template kunne, men jeg kan kun anbefale at tage et kig på den. Det er meget let at sætte op. Du kan hente T4 templaten her

Bemærk at du nok ønsker at compile dine MVC views, for at få maksimalt udbytte af denne template.

Tags:

.NET | ASP.NET | MVC

MVC-Spagetti – Et gammelt problem i nye patterns

by Jesper Blad Jensen aka. Deldy 17. October 2009 18:17

Tænk dig, hvordan vi ville se ud i hovedet, hvis en sagde til os, for bare ganske få år siden, at code-tags i din HTML ville vende tilbage, og lige pludselig blive hyldet? Det er jo nærmest det der er sket idag - og jeg så det ikke komme. Denne post handler om disse code-tags og om at vi må tage nye metoder ibrug, for at holde spegetti-koden i skak.

ASP.NET MVC er for mange frelsen fra Webforms. Webforms ses af mange, som en fejltagelse. Jeg giver dem dog ikke ret i at det var en fejltagelse, at prøve at tage et andet perspektiv på webudvikling. Tænk hvor vi havde været uden at lære af webforms, og tænk hvor mange fede ting der er lavet i webforms, og bliver udviklet i webforms i fremtiden? Webforms er og bliver en god platform, og denne post handler dog ikke om webforms, men om MVC.

Jeg er stadig ikke solgt til at kode også høre til i HTML'en. I mine øjne høre HTML til i HTML'en, og kode til i kode-filer. Men jeg er dog klar over at vi selvfølgelig bliver nød til at have nogle hooks, for at få disse ting til at spille sammen. I Webforms, var det server kontroller som var disse hooks. I ASP.NET MVC, er de de så kaldte HtmlHelpers, og vores det velkendte foreach loop. Jeg giver folk ret i at det ene kan være lige så godt som det andet. Det genialle ved webforms server kontroller er bare det, at de ikke er særligt fleksible. I MVC Views, kan vi alt for let komme til at "se lyset", og lige pludselig kode kompleks logik i vores HTML. Jeg siger ikke at det er umuligt at skrive pæne views i ASP.NET MVC, men det er bare meget sværre at lade sig rive med, og lige pludselig have if-statements over det hele.

Derfor er vi nød til at holde os selv lidt mere i ørene, for at få noget godt HTML, vi kan vedligeholde i MVC. Tilgengæld får vi også 100% det vi beder om – hvilket er et stort plus for os, som føler os godt hjemme i HTML. Dog vil jeg gerne have jer til at tænke på seperation of concerns. Det er et af de punkter som skulle være rigtig godt i MVC, men mange glemmer dette, når de laver deres views.

Javascript er vores nye code-behind

En af de ting som kan hjælpe os meget med denne problemstilling er Javascript. Her snakker jeg ikke om AJAX, og andre pletfjernere, men om at bruge Javascript til at generere og styre din HTML. De fleste kender jQuery, og diverse demo’er, med at en liste lige pludselig bliver til et galleri, bare fordi du giver dit tag en class attribute. Når du ser disse demoer, så læg mærke til hvor lidt HTML du har behov for at skrive og vedligeholde. Javascript står altså for at transformere dit plain-html dokument til noget fedt. Denne tankegang kan give dig effektive web-applikationer som er lette at vedligeholde, fordi vores kode, i vores views, nu kun skal skrive så lidt ud i HTML, som er nødvendigt for at få dit resultat.
Galleriet er et godt eksempel på hvor simpelt du kan lave noget, ved at javascript står for en del af din HTML-genering. Men hvad med alt det i din kode, som ikke er et galleri? Her kommer en liste med normale ting du normalt skriver en del kode i dit view for at opnå, og løsningerne ved at bruge javascript:

  • Alternating-items: Vi kender alle det, at vi ønsker zebra striber på vores tabeller. Vi skriver typisk en del kode, som gør at vi kan give hver anden række en bestemt CSS-klasse, som vi så kan give en anden farve. Ved at bruge jQuery, kan vi gøre dette på en linie javascript: $(“.myTable:even”).addClass(“alt”)
  • Conditional HTML eller styling: Vi har typisk en problemstilling hvor noget HTML skal vises hvis en bestemt condition er opfyldt. Dette kan f.eks. være at hvis en bestemt person har været syg i en uge, så skal hans profil vises med rød. Dette kan give en masse if-sætninger i din kode. I javascript kan du løse dette ved at kigge på de data der er printet ud, og derefter lave beslutningen om han skal være rød. På denne måde, er det nemt at tilføje at han skal være gul efter en periode, uden at dit view bliver endnu mere rodet, da javascriptet er gemt væk i sin egen fil – faktisk lidt ligesom vores code-behind fil. :)
  • Gentaget HTML: Tit har man en liste, hvor hver række indeholder en masse delt HTML. Dette kunne f.eks. være at alle items i listen kan redigeres, slettes osv. Dette producere en masse HTML, som javascript nemt kan generere. Tænk hvis du bare kunne skrive din tabel således:
    <table class="updateable deletable stripes">
        <tr>
            <td>1</td>
            <td>Jesper</td>
            <td>Jensen</td>
        </tr>
        <tr>
            <td>2</td>
            <td>Knud</td>
            <td>Hansen</td>
        </tr>
    </table>

Som du kan se, så har vi meget simpel HTML, men vores javascript vil nu sørge for at tilføje det HTML der er nødvendigt for at tilføje et update-link og et delete-link. Bemærk også at hvis du har en liste med 100 items eller mere, så kan det faktisk blive en ganske god del af HTML du spare per gang personen besøger denne side, og selve javascript transformationen kan meget vel gå hen at tage kortere tid, end at hente HTML’en.

Er jeg nu frelst for spagetti kode?

Nej desvære ikke helt. Man skal hele tiden opveje hvor meget javascript der skal til, for at gøre ens views bare en lille smule mere neme at vedligeholde. Du skal jo huske at vores javascript også skal vedligeholdes, og det er vigtigt at veje begge løsninger, før du laver en beslutning – bare husk at dine views, skal være nemme at vedligeholde – lige som resten af din kode.

Happy shooting coding

Tags:

Lazy Loading

by Jesper Blad Jensen aka. Deldy 26. June 2009 15:44

Lazy Loading er et design-pattern, hvor man definere at man venter med at hente noget data, til der er behov for det. Lazy Loading kan især være smart i forbindelse med child-relations i databaser, men det kan også være smart i forhold til dyre beregninger eller andet. Jeg vil i dette indlæg snakke om hvordan man implementere Lazy loading i din egen kode, og hvordan du sikre dig, at du opnår løs kobling, samtidig med at få lazy loading funktionalitet.

Der opstår tit problemmer i programmering, hvor du gerne vil have et rent interface til at snakke med din domaine model. Du vil gerne kunne sige foreach(Order.OrderLines), og på den måde skjule for din bruger, at du faktisk laver et ekstra kald til databasen, for at få de ekstra ordre linjer ud fra din datakilde. Det gør det meget nemt at programmere op imod dine objekter, uden at man skal tænke på hvordan objekterne bliver fundet frem. Jeg har igennem tiden lavet meget kode, hvor jeg først henter ordren, og bag efter henter alle ordre linierne ved at lave to metoder, ala dette:

   1: Order objOrder = OrderProvider.GetOrder(intOrder);
   2: OrderLines[] objOrderLins = OrderProvider.GetOrderLines(intOrder);

Der er sådan set ikke noget problem med dette, dog synes jeg selv det er pænere bare at kunne sige:

   1: Order objOrder = OrderProvider.GetOrder(intOrder);
   2: OrderLines[] objOrderLins = objOrder.OrderLines;

Men problemet opstår nu i om hvornår vi skal indlæse disse ordre linjer, for der kan jo opstå situationer hvor jeg ikke skal bruge dem til noget. (f.eks. vil jeg bare vil liste mine ordre ud, med dato) I de tilfælde vil det give ekstra overhead at læse alle disse ordre linjer ud. I langt de fleste systemer er det dog ikke et problem, da denne operation ikke er dyr, men jeg har valgt dette eksempel for at gøre det simpelt, og princippet er det samme lige meget hvad for en child-relation du snakker om.

Dog er dette et nemt problem at løse ved hjælp af Lazy Loading. Hvis du går ind under ASP.NET's wiki, og finder Lazy Loading finder du en meget simpelt implementering af dette princip:

   1: public class Order
   2: {
   3:     private int _OrderId = 0;
   4:     private int OrderId
   5:     {
   6:         set { _OrderId = value; }
   7:         get { return _OrderId; }
   8:     }
   9:  
  10:     private Customer _Customer = null;
  11:     public Customer Customer
  12:     {
  13:         get
  14:         {    
  15:             if (_Customer == null)
  16:                 _Customer = Customer.GetCustomerByOrderId(_OrderId); // Lazy loading the Customer
  17:             return _Customer;
  18:         }
  19:         set { _Customer = value; }
  20:     }
  21: }

Som du kan se her, kalder vi vores data metode, i vores get hvis den ikke allerede er indlæst. Men det der er sket her, er at vores klasse lige pludselig kender til vores datalag - og det vil vi tit gerne undgå.
Vi vil gerne have at vores datalag kan oprette en 100% færdig ordre, som får alt information at vide fra vores datalag, så vores kommunikation går fra datalaget til klassen. For at opnår dette kræver det lidt en anden tankegnag om hvordan lazy loading implementeres:

   1: class Program
   2: {
   3:     static void Main()
   4:     {
   5:         var provider = new PersonProvider();
   6:         var p = provider.CreatePerson("Hans");
   7:  
   8:         Console.WriteLine("Person created: " + p.Name);
   9:  
  10:         Console.WriteLine("Friends:");
  11:         foreach(Person person in p.Friends)
  12:         {
  13:             Console.WriteLine(person.Name);
  14:         }
  15:  
  16:         Console.ReadLine();
  17:     }
  18:  
  19:     
  20: }
  21:  
  22: class PersonProvider
  23: {
  24:     public Person CreatePerson(string name)
  25:     {
  26:         //Vi laver en ny person. 
  27:         //Bemærk at vi sender GetFriends metoden med, 
  28:         //så vores person objekt ved hvem den skal spørge hvis den mangler nogle venner.
  29:         return new Person(GetFriends) { Name = name };
  30:     }
  31:     public IEnumerable<Person> GetFriends(Person p)
  32:     {
  33:         Console.WriteLine("Executing lazy GetFriends");
  34:         return new[]
  35:                    {
  36:                        CreatePerson("John"),
  37:                        CreatePerson("Sven"),
  38:                        CreatePerson("Åge"),
  39:                        CreatePerson("Knud")
  40:                    };
  41:     }
  42: }
  43:  
  44: class Person
  45: {
  46:    
  47:     public Person(Func<Person,IEnumerable<Person>> getFriendsMethod)
  48:     {
  49:         GetFriendsMethod = getFriendsMethod;       
  50:     }
  51:  
  52:     public string Name { get; set; }
  53:  
  54:     //Dette er beskrivelsen af den metode som vi bruger til at få vores venner.
  55:     private Func<Person,IEnumerable<Person>> GetFriendsMethod { get; set; }
  56:  
  57:     private IEnumerable<Person> _friends;
  58:     public IEnumerable<Person> Friends
  59:     {
  60:         get
  61:         {
  62:             //Hvis vi ikke har indlæst listen endnu, så beder vi om listen
  63:             if (_friends == null)
  64:                 _friends = GetFriendsMethod.Invoke(this);
  65:  
  66:             return _friends;
  67:         }
  68:     }
  69: }

Som du kan se her, er det direkte metode kald til vores datalag udskiftet med en delegate til en metode som vores person kan kalde. Det betyder at vi nu kan give den alle metoder, så længe de returnere en IEnumerable<Person>, og modtager en person som argument. Bemærk at du nok i dine rigtige applikationer ville sende f.eks. PersonID med i metoden, istedet for hele objektet. Det der beskriver vores metode er: Func<Person,IEnumerable<Person>>. Det første generiske type er Person, og den beskriver at vores metode tager en person som argument, og den sidste fortæller at vi sender en liste af personer tilbage.

Dog kan vi inkapsle denne funktionalitet ned i en type, jeg har valgt at kalde LazyCollection. På den måde kan vi helt fjerne alt form for kode fra person klassen, så den ved absolut intet:

   1: class LazyCollection<TReturn> : IEnumerable<TReturn>
   2: {
   3:     private IEnumerable<TReturn> _internalData;
   4:     private readonly Func<IEnumerable<TReturn>> _methodToCall;
   5:  
   6:     public LazyCollection(Func<IEnumerable<TReturn>> methodToCall)
   7:     {
   8:         _methodToCall = methodToCall;
   9:     }
  10:  
  11:     public IEnumerator<TReturn> GetEnumerator()
  12:     {
  13:         if (_internalData == null)
  14:             _internalData = _methodToCall.Invoke();
  15:  
  16:         return _internalData.GetEnumerator();
  17:     }
  18:  
  19:     IEnumerator IEnumerable.GetEnumerator()
  20:     {
  21:         return GetEnumerator();
  22:     }
  23: }

Denne collection tager et generisk argument, lige som en IEnumerable. I dens contructor tager den en metode som kan retunere en liste af IEnumerable<Person>. På den måde kan vi nu nøges med at skrive dette i vores person klasse:

   1: class Person
   2: {
   3:     public string Name { get; set; }
   4:     public IEnumerable<Person> Friends { get; set; }
   5: }

Som du kan se, så ved person absolut intet om lazy loading, da den bare kender til en IEnumerable, men da vores LazyCollection nedarver fra IEnumerable, så kan vi sætte den collection ind der. Vores Create metode i vores PersonProvider, er også lavet om til at give vores person klasse denne collection:

   1: public Person CreatePerson(string name)
   2: {
   3:     var person = new Person();
   4:     person.Name = name;
   5:     person.Friends = new LazyCollection<Person>(()=>GetFriends(person));
   6:     
   7:     return person;
   8: }

Som du kan se sætter vi nu person.Friends lig med en ny LazyCollection. Bemærk dettte udtryk:

()=>GetFriends(person)

Dette er et lambda udstryk, som “mapper” vores GetFriends metode, som tager et argument, til en anonym metode som ikke tager nogen argumenter. På denne måde kan vi nu tage alt fra nul til mange argumenter i vores GetFriends metode, og stadig bruge den samme collection.

Jeg har i denne artikel snakket kort om Lazy Loading. Jeg har også givet et eksempel på at fjerne dette lazy loading ansvar fra vores dataklasse til vores datalag. Til sidst har jeg også givet jer en klasse, som i kan bruge i jeres projekter, til nemt og elegant, at implementere Lazy Loading ved hjælp af vores LazyCollection.

HELE KODEN:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace LazyConsole
{
    class Program
    {
        static void Main()
        {
            var provider = new PersonProvider();
            var p = provider.CreatePerson("Hans");
 
            Console.WriteLine("Person created: " + p.Name);
 
            Console.WriteLine("Friends:");
            foreach(Person person in p.Friends)
            {
                Console.WriteLine(person.Name);
            }
 
            Console.ReadLine();
        }
 
        
    }
 
    class PersonProvider
    {
        public Person CreatePerson(string name)
        {
            var person = new Person();
            person.Name = name;
            person.Friends = new LazyCollection<Person>(()=>GetFriends(person));
            
            return person;
        }
        public IEnumerable<Person> GetFriends(Person p)
        {
            Console.WriteLine("Executing lazy GetFriends");
            return new[]
                       {
                           CreatePerson("John"),
                           CreatePerson("Sven"),
                           CreatePerson("Åge"),
                           CreatePerson("Knud")
                       };
        }
    }
 
    class Person
    {
        public string Name { get; set; }
        public IEnumerable<Person> Friends { get; set; }
    }
 
    class LazyCollection<TReturn> : IEnumerable<TReturn>
    {
        private IEnumerable<TReturn> _internalData;
        private readonly Func<IEnumerable<TReturn>> _methodToCall;
 
        public LazyCollection(Func<IEnumerable<TReturn>> methodToCall)
        {
            _methodToCall = methodToCall;
        }
 
        public IEnumerator<TReturn> GetEnumerator()
        {
            if (_internalData == null)
                _internalData = _methodToCall.Invoke();
 
            return _internalData.GetEnumerator();
        }
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

Tags: , , ,

At være hobby programmør - dengang og nu

by Jesper Blad Jensen aka. Deldy 25. April 2009 14:14

Man siger at detaldrig har været nemmere at lave et program, som det er i dag. Men er dette nuogså rigtigt? I takt med at vores teknologier bliver mere avanceret, er kravetfor en applikation også blevet større. Jeg vil i denne artikel snakke om atvære hobby programmør, og om det virkelig er lettere at være hobby programmør idag, end det var tidligere?

Jeg er en af de programmører som programmere for interessensskyld. Jeg programmere fordi jeg synes det er spændende, sjovt og udfordrende.Jeg arbejder selvfølgelig også som programmør, men det er vigtigt for mig, bådeat få lov til at lave noget skørt her hjemme, sammen med at man laver det mereseriøse på arbejdet. Nu arbejder jeg heldigvis på en af de arbejdspladser, hvorvi godt engang i mellem må gå "out-of-the-box" og undersøge nyespændende ting. Dog er det stadigvæk dejligt befriende at få lov til atprogrammere som hobby.

Jeg er en ung programmør, i det kræse som jeg befinder migi. Jeg snakker meget tit med programmører som har lagt mere erfaring end mig,og det er heldigt, da man lære en masse af folk som har lavet alle de fejl manendnu ikke selv har begået.
Fælles for disse programmører er tit, at de er startet meget før med atprogrammere end mig (forhåbentlig). Derfor har de programmeret i sprog ogteknologier som hørte til i DOS og andet gøgl.
Nogle af disse programmører er også vokset op med programmering som en hobby,ligesom mig selv. De startede deres dage ved at programmere små spil, inventarsystemer, eller andre små tools, som de ikke havde adgang til. I dag har viinternettet, hvor du nu snart kan finde alle former for systemer til disse småting, som man lavede programmer til førhen. Det betyder at man i dag, som hobbyprogrammør, enten skal lave et program meget anderledes, end de hundredvis derfindes på markedet, eller lave noget bedre.
Med internettet er udbuddet af programmer vokset markant, og det har heldigvisbetydet at programmer, der løser ens problem, tit ikke er langt væk. Dettebetyder så desværre også for hobby programmøren, at han nu ikke mangler disseprogrammer som han kan programmere for at løse et problem - dette kan han istedet bare skaffe. Udover dette så er barrieren for hvornår et program er fedtnok til at man selv gider at bruge det, steget markant. I "gamle"dage, var et konsol program fedt, hvor man bare så tal og tekst. I dag skal etprogram helst være en visuel perle, der er innovativ, let og samtidigoverholder utallige standarder.

Vi kan tage et eksempel, med et computerspil. I gamle dage,tog det én mand for at lave et spil, grafikken kunne han selv klare, for denvar stort set ikke eksisterende. Så kom behovet for en grafikker, og nu er derhundrede vis af folk indblandet i konstruktionen af et spil. Vi vil i dag ikkespille et spil, med mindre det er flot og har god grafik. Lever det ikke op tilens forventninger, så bliver det kastet væk, for udbuddet af spil er enormt.Dette har også resulteret i at procentdelen af spil lavet af små teams, erfaldet markant, selvom der stadigvæk findes nogle perler. Dette har da ogsåbetydet at hobby spil programmører har svære ved at være tilfredse med deres kreationer,da det jo ikke ligner Crysis, selvom det var målet.

 

 

Jeg frygter at dette er begyndt at ske med software. Vi er begyndtat kræve, at et program ser visuelt godt ud, før vi gider at bruge det. Dettebetyder jo så også, at der er ved at ske det samme med hobby miljøet forprogrammering, som der er med spil - de er der stadig, men  chancen for at de selv bliver tilfreds medderes programmer er mindre.

 

Så hvad kræver det i dag at lave et program som er"brugbart"?  Er det virkeligblevet nemmere at lave et program i dag, eller har behovene for et programsteget så markant, at det faktisk er blevet sværere at være hobby programmør iet samfund som i dag, hvor et bedre program bare er få klik væk?


Jeg er bange for at jeg bliver nød til at svare ja til dettespørgsmål, men hvad synes du?

Tags:

Fil hosting i skyen - Amazon S3

by Jesper Blad Jensen aka. Deldy 9. April 2009 14:22

Jeg har en ven (Søren Pedersen) som p.t. er igang med at lave en hjemmeside. Denne hjemmeside skal fungere som et community hvor brugerne har mulighed for at skrive deres status, som uploade nogle billede o.lign. 

Vi har snakket sammen om hvordan han bedst griber det an; at lave siden på en smart måde, som gør, at der er mindst muligt arbejde i den, smat gøre den fleksibel. Vi har valgt at prøve at "outsource" så meget af hjemmesiden som muligt. Derfor er han alderede begyndt på at implementere OpenID på hjemmesiden, hvilket blev gjort nemt ved at bruge DotNetOpenAuth. Det tog omkring 30 minuter at få OpenID delen til at virke, og så var han ude over problemmet med at gemme folks adgangskoder, og tvinge folk til at oprette en profil. Vi blev begge overrasket over hvor nemt dette var, og når det tager maks 30min at sætte din side op til OpenID, hvorfor så ikke gøre det?

At outsource brugergodkendelse, var jo ligesom en no-brainer, men det næste vi har set på, er hvordan vi outsourcer billederne som brugerne skal kunne uploade. Min ven havde kigget lidt på Flickr, som jo er en galleri-hjemmeside hvor folk kan uploade deres billeder. Problemmet er at det faktisk kræver at brugerne nu er medlem af 2 sider: En OpenID provider og Flickr.
Udover at vi nu gør det besværligt for folk at uploade billeder med mindre de "heldigvis" er medlem af Flickr, så skulle der også til at laves et helt lille system som snakker med Flickr's API. Min ven undersøgte det lidt nærmere og fandt ud af at det faktisk koster penge at bruge Flickr's API, hvis man tjener penge på den hjemmeside som bruger det. Da denne hjemmeside gerne skulle ende med at blive reklame-financeret, så skulle man jo så også hen og betale for at bruge deres API.

Selvom vi slet ikke har droppet at kigge nærmere på Flickr, så faldt jeg idag over Amazon S3. S3 er en slags fil-server oppe i skyen, hvor du kan ligge dine filer. Det smarte ved S3 er at du betaler for hvor meget du bruger denne lagerplads, så ved en lille hjemmeside, som har lidt trafik, koster det meget lidt at bruge S3, og ved større hjemmesider koster det så mere. Dette passer jo godt overens med reklamer, hvor man tit også for flere penge fra reklamer når siden er populær. Vi har regnet ud at til at starte med vil det kun koste mindre en 1 dollar om måneden at bruge S3, da der ikke vil være så mange billeder og besøgende. Senere vil det selvfølgelig koste mere. Lad os prøve at lave et eksempel på hvor meget S3 evt. kunne komme til at koste for ham:

Lad os sige at der er omkring 10.000 besøgende om måneden. Der er omkring 50000 billeder som fylder omkring 100kb stykket. Dette er altså i alt omkring 5gb data. Dette kommer til at koste 0.9$ om måneden.
Disse 10.000 besøgende ser gennemsnitligt 3 billeder per besøg og ligger 1 op, altså bruger hver bruger 400kb data. Det er altså 3 gb data ned og 1gb data op. Dette kommer til at koste 1$ om måneden.
Altså kommer dette til at koste omkring 2$ (14 kr) om måneden. Bemærk at vi selvfølgelig stiger med 1gb per måned ud over de 5gb, så derfor vil dette forbrug sige. Hver gb koster 0.180$ om måneden. Det vil sige at vi kommer op på 17gb på et år, altså vil den totale pris blive 4.150$ (30 kr) efter 1 år.

Som i kan se, så er prisen ikke så vanvittig høj. Samtidig så får du høj stabilitet på dine filer, samt høj hastighed for upload og download. Det gør S3 vanvigttig interesandt, da det jo selvfølgelig kan bruges til alle former for filer. Samtidig er der et fuldt API bag S3, som gør det muligt at upload og downloade filer, samt en masse andet spændende. Udover dette tilbyder S3 også Bittorrent support til f.eks. podcasts og lign.

Jeg har kigget lidt på integrationen mellem .NET og S3, og selvom dokumentationen på Amazons side er lidt rodet, så brugte jeg min trofaste ven Google, og fandt frem til at der findes et bibliotek ved navn ThreeSharp, som gør det utroligt let og smertefrit at uploade filer til S3.

Alt i alt virker S3 som en intersandt mulighed for at hoste filer, selvom det selvfølgelig altid er nemmere rent teknisk bare at kigge dem lokalt på webserveren eller i databasen, så giver S3 nogle helt klare fordele. Om vi ender med at beslutte at bruge S3, Flickr eller lokal fil hosting må tiden vise, men jeg synes S3 var et intersandt koncept, så tænke lige jeg ville dele mine erfaringer :)

Er der nogen der har nogle erfaringer med S3, eller nogle gode råd til hvordan vi bedst giver brugerne mulighed for at uploade billeder? Vi er meget åbne for ideer, da dette problem gerne skal løses bedst muligt.

Tags:

Så er første måned gået

by Jesper Blad Jensen aka. Deldy 28. February 2009 08:04

Ja, så er første måned som værnepligtig gået.

Jeg har ikke skrevet så meget om selve værnepligten, som jeg måske har lovet jeg ville gøre, men i stedet for at spamme jer med nye små posts på daglig basis, har jeg besluttet mig for at lave en månedlig opdatering.

Det skal ikke være nogen hemmelighed, at jeg havde en del forestillinger om hvordan, det ville være at være værnepligtig. For det første har jeg indtryk fra film, og ikke mindst folks ”skræk” historier fra dengang de var soldat. Derfor kom jeg afsted med den forestilling at det hele var meget striks, og lige meget hvad man gjorde, så ville der stå en sur befalingsmand og spytte dig i hovedet.

Nu kan jeg jo selvfølgelig ikke snakke om alle steder man kan være værnepligtig, men hos Telegrafregimentet hvor jeg er, så er ingen af disse forestillinger holdt stik. Jo, der findes selvfølgelig visse befalingsmænd som let bliver lidt sure, men så er det tit når folk har lavet en dum ting, som de måske gjorde med vilje. Så længe man gør sit bedste hele tiden, så er man godt rustet.

Men de befalingsmænd som er i min deling, ser alle ud til at have lært, at man kommer længere med ros, end råb og skrig. Problemet opstår nemlig, at hvis en person er sur hele tiden, så vil man på et tidspunkt blive lidt ligeglad. Selvfølgelig kan de sagtens hæve stemmen, når vi laver såkaldt ”cluster-fuck” i det, men det er ikke på den måde, hvor man render rundt hele dagen og har det dårligt i maven over, at man har fået kæmpe skider – og det er vigtigt hvis man skal kunne lide at være der.

Det er også vigtigt at kunne have det sjovt men ens befalingsmænd, og det kan vi. Selvfølgelig er der tider hvor alt skal være seriøst, men der findes også tidspunkter hvor vores befalingsmænd stiller sig på lige fod med os værnepligtige, ved at vi kan snakke med dem, som var de en del af værnepligt-gruppen. De laver tit rigtig meget sjov, og er alle sammen rigtig gode til at lære fra sig.
Der findes altså ikke denne befalingsmands overklasse, som man måske kunne frygte.

De første par uger var utrolig hårde med dage hvor vi stod op kl. 6:15 og fik fri kl. 22:00. Det er dog heldigvis blevet afløst af dage hvor vi typisk har fri kl. 15 eller 17. Det sjove er at efter to uger af ca. 15 timers arbejdsdage, så er 10 timers arbejdsdage jo bare luksus!
Så selvom de første to uger var et helvede, med alt for mange indtryk, på samme tid, 41 andre personer, plus befalingsmænd, som man skal lære at kende, og en bjerg af udstyr som man skal holde styr på, så er de heldigvis overstået. De sidste to uger har været rigtig gode, selvom de også til tider har været hårde. Vi har fået skudt med gevær, samt rendt rundt i skoven under pigtråd, og hvad der nu måtte høre til dette. Det har været sjovt og hårdt, men blandingen mellem praksis og undervisning, har været rigtig god, så selvom vi har haft det hårdt en dag eller to, så har vi kunne genlade lidt de andre dage.

Det er selvfølgelig en anden verden af komme til. Vi bor fire på samme værelse, og selvom de på ingen måde er lige så mange, som andre steder, så er det alligevel anderledes at bo sammen med andre. Du har ikke dette privatliv, som du måske havde hjemme. For mit vedkommende har det ikke været det store problem. Det er nok også bevirket af, at jeg bor sammen med min kæreste i en relativ lille lejlighed, så jeg kender det med at der altid er en anden der kan høre og se hvad du laver. Det vigtige her, er at folk giver hinanden plads, og at man kan være i samme rum, og laver hver sin ting, og lade den anden være i fred. Det er gået rigtigt godt. Jeg er heldigvis kommet på værelse med tre rigtig rare og flinke personer, hvor vi nemt kan blive enige om nogle værdier og normer. Dette er selvfølgelig også gjort nemmere af at vi kun er disse fire personer.

Jeg er kommet frem til i løbet af disse 4 uger, at så længe jeg tager værnepligten som en fire måneders uddannelse, i stedet for 4 månederne slavearbejde, så er værnepligten slet ikke så slem. Jeg er ikke længere ked af, at jeg er værnepligtig. Det er træls at blive tvunget til noget, men som vores kaptajn siger, så er der flere undersøgelser som viser, at personer som har været værnepligtige, har fået nogle værdier med i bagagen som gør dem mere rustet til de forhindringer der måtte komme i ens liv.

Nu står næste uge på vores første felt-døgn hvor vi skal smage de frygtede felt rationer, og sove under åben skybrud. Men så har vi da i det mindste fri torsdag og fredag. Smile

Tags:

Militær

Og vejen går til militæret

by Jesper Blad Jensen aka. Deldy 1. February 2009 11:56

Til de af jer der ikke ved det. Så har værnepligten hængt over mig, som en sort sky, siden jeg var til session for en del år siden. Jeg udskudte det, da det passede rigtigt dårligt til mine uddannelsesplaner, men nu er muligheden for at udsætte slut. Den sorte sky er begyndt at tisse med sne (se bare ud af vinduet - great), og i morgen begiver jeg mig på den store rejse (der vare hele 45minuter) fra Odense til Fredericia kaserne.

I løbet af min udsættelse er jeg blevet rykket fra Skive til Fredericia kasserne, hvilket passer mig fint. Grunden til dette har været at jeg er færdiguddannet datamatiker, og så var det mest relevante sted for mig at komme i militæret, åbenbart i telegraftropperne.
Jeg har en lidt delt følelse af, at komme på slave skole her i fire måneder. På en måde glæder jeg mig, for det skal nok blive en oplevelse, men det bliver også hårdt - især fysisk, da mig og i-form aldrig rigtigt har snakket så godt sammen :)

I den her tid, bliver det nok ikke til så meget programmering, men jeg vil prøve om jeg kan få kodet en linje eller to, mellem armbøjningerne, og 10km løb. Når jeg har kodet den ene linje eller to, så vil jeg også blogge om mine oplevelser inde i BS-Land, og prøve at lave et specielt teknisk edge på det - vi er jo nørder :)

Derfor vil du nok i de næste fire måneder ikke høre så meget om programmerings-eventyr, men mere om mudderbadning, og hul-gravning på tid.
 

Stay tuned

Tags: ,

Understøtter det her produkt mit operativ system?

by Jesper Blad Jensen aka. Deldy 8. January 2009 17:17

Jeg var lige inde og kigge på en download fra Microsoft, og under operativ systemer står der dette:

 

Supported Operating Systems: Windows Server 2003; Windows Server 2003 Itanium-based editions; Windows Server 2003 R2 (32-Bit x86); Windows Server 2003 R2 Datacenter Edition (32-Bit x86); Windows Server 2003 R2 Datacenter x64 Edition; Windows Server 2003 R2 Enterprise Edition (32-Bit x86); Windows Server 2003 R2 Enterprise x64 Edition; Windows Server 2003 R2 Standard Edition (32-bit x86); Windows Server 2003 R2 Standard x64 Edition ; Windows Server 2003 R2 x64 editions; Windows Server 2003 Service Pack 1; Windows Server 2003 Service Pack 1 for Itanium-based Systems; Windows Server 2003 Service Pack 2; Windows Server 2003 Service Pack 2 for Itanium-based Systems; Windows Server 2003 Service Pack 2 x64 Edition; Windows Server 2003 x64 editions; Windows Server 2003, Datacenter Edition (32-bit x86); Windows Server 2003, Datacenter Edition for 64-Bit Itanium-Based Systems; Windows Server 2003, Datacenter x64 Edition; Windows Server 2003, Enterprise Edition (32-bit x86); Windows Server 2003, Enterprise Edition for Itanium-based Systems; Windows Server 2003, Enterprise x64 Edition; Windows Server 2003, Standard Edition (32-bit x86); Windows Server 2003, Standard x64 Edition; Windows Server 2003, Web Edition; Windows Server 2008; Windows Server 2008 Datacenter; Windows Server 2008 Datacenter without Hyper-V; Windows Server 2008 Enterprise; Windows Server 2008 Enterprise without Hyper-V; Windows Server 2008 for Itanium-based Systems; Windows Server 2008 Standard; Windows Server 2008 Standard without Hyper-V; Windows Small Business Server 2003 ; Windows Small Business Server 2008 Premium; Windows Small Business Server 2008 Standard ; Windows Vista; Windows Vista 64-bit Editions Service Pack 1; Windows Vista Business; Windows Vista Business 64-bit edition; Windows Vista Business N; Windows Vista Enterprise; Windows Vista Enterprise 64-bit edition; Windows Vista Home Basic; Windows Vista Home Basic 64-bit edition; Windows Vista Home Basic N; Windows Vista Home Premium; Windows Vista Home Premium 64-bit edition; Windows Vista Service Pack 1; Windows Vista Starter; Windows Vista Starter N; Windows Vista Ultimate; Windows Vista Ultimate 64-bit edition; Windows Web Server 2008; Windows XP 64-bit; Windows XP Embedded; Windows XP Embedded Service Pack 1; Windows XP Embedded Service Pack 2 ; Windows XP for Itanium-based Systems Version 2003; Windows XP Home Edition ; Windows XP Home Edition N; Windows XP Media Center Edition; Windows XP Media Center Edition 2005 Update Rollup 2; Windows XP Professional 64-Bit Edition (Itanium) ; Windows XP Professional 64-Bit Edition (Itanium) 2003; Windows XP Professional Edition ; Windows XP Professional N; Windows XP Professional x64 Edition ; Windows XP Service Pack 1; Windows XP Service Pack 2; Windows XP Service Pack 3; Windows XP Starter Edition


Kan i finde mit operativ system i listen? Windows Vista Business x64? Der er en pæn slat operativ systemer.
Kunne de evt. ikke bare filtere det ud fra min user agent, som er: Mozilla/5.0 (Windows; U; Windows NT 6.0; da; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)?

Det der er da ubrugeligt Smile Og ikke nok med det, så er den sikkert ikke komplet. Windows 7 beta er der f.eks. ikke, men der virker den pågældende ting fint.

 

Så et forslag til Microsoft. Erstat dette med:

Supported Operating Systems: Windows XP / Windows Server 2003 or Higher

eller simplere:

It will properbly work, but try and see - good luck!

 

Det er et bevis på en ting, som virker fint med få records, men så bliver systemet ældre - der kommer flere records - og lige pludselig er det et stort rod. 

 

 

Tags:

Skal vi virkelig tvinge vores brugere til at skifte kodeord?

by Jesper Blad Jensen aka. Deldy 3. January 2009 15:07

Her for nyligt skulle jeg ind på Fionia Netbank. Da jeg havde logget ind blev jeg bedt om at skrifte kodeord.

Jeg tænker jo straks: "Nå, de har nok opdateret deres brugersystem, så jeg skal indtaste et nyt kodeord som så bliver gemt i det nye"

Jeg er jo glad for mit kodeord, ligesom 99% af befolkningen. Derfor prøvede jeg jo selvfølgelig at skrive mit gamle kodeord ind igen - men dette ville de ikke lade mig.

Ideen består fra deres side i, at ved at tvinge mig til at skifte kodeord regelmæssigt, så højner de sikkerheden. Dette er jeg uenig i.
Normale PC-brugere er dårlige til at huske kodeord. Så hvad sker der hvis jeg med jævne mellemrum tvinger dem til at skifte? Nogle af dem glemmer de deres nye kodeord, og kommer ikke igen. Men langt de fleste vælger at skrive det nye kodeord ned et sted, så de kan huske det. Hvor skriver de dette kodeord ned? De skriver det enten på et stykke papir som de ligger ved deres computer, hvis de skal bruge det tit - eller de ligger det måske sammen med papirerne til deres homebanking. Nogle skriver det også ukrypteret ind på deres computer, deres mobil eller andet.

I forbindelse med homebanking er dette RIGTIG skidt, da brugeren nu har lagt sit kodeord det samme fysiske sted, som deres nøglefil (altså deres computer). Hvis der er indbrud, så er det nu let for tyven, både at få nøglekoden, men også få koden, da den jo står på papiret. Dette problem er udbredt langt mere end man skulle tro. Der findes vigtige systemer i det offentlige som tvinger brugerne til at skifte kodeord, og utroligt mange af dem skriver deres kode ned på et stykke papir, og ligger dem ved computeren. Nu er det så lige til, for en person der går forbi, at logge ind, og lave rod i systemet. Nu ved jeg ikke præcis hvad for nogle offentlige systemer der fungerer sådan, men jeg ved at de findes. Forestil dig at politiets computere, eller sygehusenes computere fungerede sådan. Det ville ikke være kønt.

Fioniabank har her gjort sig selv en bjørnetjeneste, da de ved at tvinge deres brugere til at skifte kodeord, faktisk har gjort deres brugere mere udsatte. Tvunget skift af kodeord er en dårlig ide - det er i orden at fortælle brugeren at personen har haft det kodeord i for lang tid, og at de bør skifte det, men gør man det andet - så opstår problemet. Er det vigtige systemer, så tving hellere brugerne til at have et lidt mere avanceret kodeord, som de stadig har mulighed for at huske, men som er så sikkert, at de nok vælger at bruge et andet kodeord til deres personlige log-ind’s til underlige sider om viagra.


Så stop med at tvinge os til at skifte kodeord! Jeg gik alligevel ind og skiftede den om til det gamle, efter jeg var tvunget til at vælge et nyt - så kan I lære det!
 


Hvad synes i om tvunget skiftning af kodeord? Er det en god eller dårlig ide? Tager jeg helt fejl?

Tags: , ,

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

Disclaimer

opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.