ASP.NET: Schichtentrennung – Implementierung

Das Schicke an der Schichtentrennung und den damit verbundenen Konzepten, ist, dass die Implementierung später gegen eine andere Implementierung ausgetauscht werden kann. Genau diesen Ansatz macht man sich zu Nutze, wenn man schnell Ergebnisse erzielen möchte, indem man zunächst eine einfache Implementierung erstellt und eben erst später die echte, große, datenbankgestützte Version bereit stellt.

Das vorausgeschickt, ist die folgende Implementierung nur als ein erster Ansatz zu sehen, den Sie durch eine Version ersetzen können, der Ihren eigenen Anforderungen besser entspricht. Die hier vorgestellte Implementierung nutzt nur den Speicher, um die angelegten Kunden vorzuhalten. Technisch macht sie nix anderes, als eine Liste von Kunden im Speicher zu halten. Einfach, aber für einen Test und einen ersten Prototypen sicherlich ausreichen.

Wichtig: Diese Komponente liegt in einem eigenen Projekt mit dem Namen MemoryCustomerManager (genau so wird der Name der Assemblierung heißen).

Der Code ist ziemlich selbsterklärend – hier werden schließlich nur Operationen auf einer Liste von Kunden vorgenommen. Damit alles später zusammen funktioniert, muss diese Implementierung somit lediglich von der Basisklasse CustomerManager erben und die benötigten Methoden implementieren:

using System;
using System.Collections.Generic;
using System.Text;
using BusinessLayer;

namespace MemoryCustomerManager
{
   ///

   /// Implementation of the business layer
   ///

   public class MemoryCustomerManager : CustomerManager
   {

      private static List _customers =
         new List
();

      ///

      /// List of customers
      ///

           
      private static List CustomersList
      {
         get { return _customers; }
      }  

      ///

      /// Returns all customers
      ///

      public override List GetAllCustomers()
      {
         // Sort
         Sort(CustomersList);

         // Return the customers
         return CustomersList;
      }

      ///

      /// Returns a specific customer
      ///

      public override Customer GetCustomer(Guid id)
      {
         // Check all customers
         foreach (Customer cust in CustomersList)
         {
            // Compare the id
            if (cust.Id.Equals(id))
            {
               // Found it!
               return cust;
            }
         }

         // Found nothing
         return null;
      }

      ///

      /// Finds all customers by their names
      ///

      public override List
         FindCustomersByName(string name)
      {
         List
customers =
            new List
();
         string nameLower = name.ToLower();

         // Check every customer
         foreach (Customer cust in CustomersList)
         {
            if (cust.LastName.ToLower()
               .Equals(nameLower))
            {
               customers.Add(cust);
            }
         }

         // Sort the customers
         Sort(customers);

         // Done
         return customers;
      }

      ///

      /// Finds all customers by their email-addresses
      ///

      public override List
         FindCustomersByEMail(string email)
      {
         List
customers =
            new List
();
         string emailLower = email.ToLower();

         // Check every customer
         foreach (Customer cust in CustomersList)
         {
            if (cust.EMail.ToLower().Equals(emailLower))
            {
               customers.Add(cust);
            }
         }

         // Sort the list
         Sort(customers);

         // Return the customers
         return customers;
      }

      ///

      /// Updates a customer
      ///

      public override Customer
         UpdateCustomer(Customer customer)
      {
         // Delete an existing customer
         DeleteCustomer(customer);

         // Add the customer
         CustomersList.Add(customer);

         return customer;
      }

      ///

      /// Deletes a customer
      ///

      public override bool
         DeleteCustomer(Customer customer)
      {
         // Check, whether the customer
         // exists in the list
         Customer existing = null;
         foreach (Customer cust in CustomersList)
         {
            if (cust.Id.Equals(customer.Id))
            {
               existing = cust;
               break;
            }
         }

         // Replace the old customer
         if (null != existing)
         {
            CustomersList.Remove(existing);
            return true;
         }

         return false;
      }

      ///

      /// Sort the customers
      ///

      private void Sort(List customers)
      {
         customers.Sort(new CustomerSorter());
      }
   }
}

Innerhalb der Klasse wird Bezug auf eine Klasse CustomerSorter genommen. Diese hat die Aufgabe, die Liste der Kunden stets alphabetisch sortiert zu halten. Wir implementieren dies mit Hilfe des Interfaces IComparer. Dabei ist lediglich die Methode Compare() zu überschreiben – und diese Überschreibung ist ziemlich simpel, denn tatsächlich geschieht nix anderes, als die Nachnamen der Kunden über deren Funktionalitäten miteinander zu vergleichen und das numerische Ergebnis dieses Vergleiches zurück zu geben. Dabei kann es zu folgenden Rückgaben kommen:

  • Zahl größer als 0: Der Wert der Instanz, auf der verglichen worden ist, ist größer.
  • 0: Beide Werte sind gleich.
  • Zahl kleiner als 0: Der Wert der Instanz, mit der verglichen worden ist, ist größer.

Dementsprechend kann das natürlich auch umgedreht werden, wenn man am Ende des Tages eine absteigende Sortierung wünscht. Wenn die Nachnamen gleich sind, werden die Vornamen miteinander verglichen. Sind auch die gleich, kommen die E-Mail-Adressen an die Reihe.

Lange Rede, kurzer Sinn: Dies ist der Code der CustomerSorter-Klasse:

using System;
using System.Collections.Generic;
using System.Text;
using BusinessLayer;

namespace MemoryCustomerManager
{
   public class CustomerSorter : IComparer
   {
      ///

      /// Compares two customers
      ///

      public int Compare(Customer x, Customer y)
      {
         int result = x.LastName.CompareTo(y.LastName);
        
         // Compare the first names when neccessary
         if (result == 0)
         {
            result = x.FirstName.CompareTo(y.FirstName);
         }

         // Compare the emails when neccessary
         if (result == 0)
         {
            result = x.EMail.CompareTo(y.EMail);
         }

         return result;
      }
   }
}

Damit ist die Implementierung komplett. Im nächsten Teil unserer Serie widmen wir uns dann der Nutzung dieser ganzen Komponenten im Web-Umfeld.

Teil 1. Teil 2. Teil 3.

2 Comments so far

  1. Andi on Juni 29th, 2008

    Danke für die viele Mühe.

    Die MemoryCustomerManager-Komponente soll ich in ein anderes Projekt.
    Werden die einzelnen Komponenten dann Kompiliert und per .dll`s in einem Projekt zusammen gefügt?

  2. Andi on Juli 15th, 2008

    Hallo,
    wird es noch einen 5. Teil geben?
    Mich würde auch noch interessieren wie man den Code an eine GUI oder an eine Webseite bindet.

    Würde mich freuen.

    Andi