ASP.NET – Diskuzní forum (1)

V dnešním dílu začneme vytvářet komponentu pro diskusní fórum. Cesta bude trnistá a náročná, ale na jejím konci bychom měli mít pokročilou komponentu pro použití v našich ASP.NET aplikacích.
Jak to už bývá na začátku každého projektu, musíme si i v případě komponenty Forum definovat cílové požadavky. Snažil jsem se o výběr toho nejlepšího, co jsem zatím na webu pochytil. Komponenta by tedy měla:
  • Obsahovat libovolný počet příspěvků, které by měli být uspořádány do stromové hierarchie (threaded discussion)
  • Umožňovat více nezávislých diskuzí, např. diskuze k článkům, diskuze v sekci know-how atd.
  • Být nezávislá na datovém zdroji. Jako datový zdroj bychom mohli použít některý z následujících přístupů:
    • SQL server s vloženými procedurami
    • Databázi Access s přístupem pomocí čistého SQL
    • NNTP news server
    • XML soubor
  • Být rychlá - neměla by zdržovat samotné zobrazení článku, nebo sekce.
  • Označovat již přečtené zprávy, podobně jak je to např. ve Outlook News Readeru.
  • Mít možnost odebírat reakce na daný příspěvek emailem.
Po této počáteční analýze můžeme ke každému s uvedených bodů přiřadit požadavek na implementaci, který danou funkci umožní:
  • 1. Obsahovat libovolný počet příspěvků, které by měli být uspořádány do stromové hierarchie (threaded discussion)

Stromovou strukturu docílíme například tím, že daný objekt Message bude jako jedno ze svých polí obsahovat kolekci všech dceřiných příspěvků, které budou také typu Message.

Na straně databázi může uvedená implementace vypadat například takto:

Klepněte pro větší obrázek

  • 2. Umožňovat více nezávislých diskuzí, např. diskuze k článkům, diskuze v sekci know-how atd.

To docílíme vytvořením samostatné tabulky Forum a odpovídajícího objektu. Ten bude obsahovat kolekci Messages, ve které budou zprávy z kořenové úrovně pro dané forum. Pro každé forum běžící v aplikaci pak bude vytvořena samostatná instance.

  • 3. Být nezávislá na datovém zdroji.

Co je to vlastně "nezávislost na datovém zdroji"? Jak docílíme toho, aby se při změně způsobu ukládání dat změnil náš kód co nejméně? Odpovědí je oddělení funkcí pro přístup k databázi od funkcí pro samotnou logiku fóra. Nejlépe by bylo, kdybychom mohli z Fóra volat určité funkce, například pro uložení dat do datového zdroje i bez toho, abychom znali konkrétní implementaci třídy, která to zajišťuje. Pro tento účel můžeme velice hezky využít rozhraní (interface), které pojmenujeme IForumDataAdapter. To bude definovat funkce pro načtení dat z datového zdroje do třídy Forum, a nebo naopak pro zápis dat zpátky v případě změny.

  • 4. Být rychlá - neměla by zdržovat samotné zobrazení článku, nebo sekce.

Pro aktuální fóra, které běží například pod novými články a jsou často zobrazované, by bylo dobré nastavit možnost cachování dat pomocí aplikační cache - rekurzivní získávání by bylo hodně pomalé. Na druhou stranu není určitě vhodné cachovat všechny fóra kvůli paměťové náročnosti, proto by bylo dobré kdyby samotná komponenta uměla tuto vlastnost vypnout.

  • 5. Označovat již přečtené zprávy, podobně jak je to např. ve Outlook News Readeru.

Této funkci můžeme docílit pomocí cookie nebo pomocí ukládání seznamu přečtených článků do proměnné session. Cookie odlehčí našemu serveru, umožní ale pouze sledování několika desítek posledních přečtených zpráv, kvůli omezení přenosové kapacity a velikosti cookie podporované jednotlivými prohlížeči. Naproti tomu použití session bude poněkud náročnější na implementaci.

  • 6. Mít možnost odebírat reakce na daný příspěvek emailem.

Implementovat tuto funkci by neměl být problém - stačí vytvořit tabulku se seznamem emailů a propojit ji s danou zprávou. Na úrovni databázového adaptéru IForumDataAdapter pak vytvoříme funkci, která nám pro zadaný příspěvek vrátí seznam odběratelů. Při zakládání nového příspěvku si necháme vypsat veškeré odběratele pro nadřazené rodičovské příspěvky a všem pošleme email s daným příspěvkem.

Výsledná architektura naší komponenty bude tedy vypadat:

Klepněte pro větší obrázek

Základní kostra implementace ve C# by pak mohla vypadat :

  namespace Components
  {
   
    /// <summary>A message for Forum. Contains child messages in _messages field.</summary>
    public class ForumMessage
    {
      private string _author;
      private string _subject;
      private string _authorEmail;
      private string _body;
      private string _IPAddress;
      private string _attachment;
      private DateTime _postDate;
      private ForumMessageCollection _messages;

      /// <summary>Author`s name or nickname typed into the submit form.</summary>
      public string Author{set{_author = value;}get{ return _author;}}
     
      /// <summary>
      /// Description of the message
      /// </summary>
      public string Subject{set{_subject = value;}get{ return _subject;}}

      /// <summary>The email address author has entered into submit form</summary>
      public string AuthorEmail{set{_authorEmail = value;}get{ return _authorEmail;}}

      /// <summary>Text of the message</summary>
      public string Body{set{_body = value;}get{ return _body;}}
     
      /// <summary>Author`s IP address</summary>
      public string IPAddress{set{_IPAddress = value;}get{ return _IPAddress;}}

      /// <summary>Name of attached file residing in special directory for uploading/downloading purposes only (no running scripts)</summary>
      public string Attachment{set{_attachment = value;}get{ return _attachment;}}

      /// <summary>Name of attached file residing in special directory for uploading/downloading purposes only (no running scripts)</summary>
      public DateTime PostDate{set{_postDate = value;}get{ return _postDate;}}

      /// <summary>Collection of child messages</summary>
      public ForumMessageCollection Messages{set{_messages = value;}get{ return _messages;}}
    }

    /// <summary>A collection of Forum messages.</summary>
    public class ForumMessageCollection:ArrayList
    {
      /// <summary>Adds a message to the collection</summary>
      /// <param name="q">message object to add</param>
      /// <returns>Index of inserted message</returns>
      public int Add(ForumMessage q)
      {
        return base.Add(q);         
      }
      /// <summary>Gets or sets message with index</summary>
      public new ForumMessage this[int index]
      {
        get
        {
          return (ForumMessage)base[index];
        }
        set
        {
          base[index] = value;
        }
      }
    }

    /// <summary>Implementation of Forum</summary>
    public class Forum
    {
      private ForumMessageCollection _messages;

      /// <summary>Collection of root messages for this Forum.</summary>
      public ForumMessageCollection Messages
      {
        set
        {
          _messages=value;
        }
        get
        {
          return _messages;
        }
      }
    }
    /// <summary>
    /// IForumDataAdapter defines an interface responsible for filling data from/into the Forum, given as a read-only
    /// property CurrentForum. This should be initialized by constructor of implementing object. This interface allows to have
    /// multiple possibilities for storing data. For example an SQL server with stored procedures, Access database with pure SQL
    /// access, XML file, or NNTP server.
    /// </summary>
    public interface IForumDataAdapter
    {
      Forum CurrentForum{get;}
      void Load();
      void Save();
      Forum Create();
      // additional implementation possible for checking for list of read messages.
    } 
  }

Flexibilita návrhu spočívá v těchto klíčových bodech:

  • Pokud budeme v budoucnu potřebovat změnit datový zdroj, přidáme pouze třídu implementující rozhraní IForumDataAdapter. Toto rozdělení nám umožní vyvarovat se chyb v důsledku změn v kódu.
  • Pokud budeme chtít vyvinout forum pro např. pro WAP, WinForms, nebo WebService, celá základna je již hotová, stačí jenom přidat samotnou implementaci komponenty.

Co bude příště ? Návrh sice může být hezký, spustit jej a přidávat příspěvky na něm ale nemůžeme. Takže příště vzhůru do programování a implementování uvedeného návrhu. Naše implementaci bude zahrnovat pouze OleDBForumDataAdapter pro ukládání dat do Accessu, pokud bude zájem, můžeme se později podívat na další možnosti (NNTP, XML).

Diskuze (4) Další článek: Finální KDE 3.0

Témata článku: Software, Programování, ASP, Seti, Public, Pure, WinForms, Only, Interface, Message, Child, Attachment, Možnost reakcí, Samostatná instance, Running, Příspěvek, Základní kostra, Sta, Celá základna, Forum, Stem, Libovolný bod, Private, Klíčový bod


Určitě si přečtěte

Jak se šíří Covid v Česku: Čerstvá data, semafor PES, mapy okresů a obcí. Každý den aktualizované grafy

Jak se šíří Covid v Česku: Čerstvá data, semafor PES, mapy okresů a obcí. Každý den aktualizované grafy

** Vývoj COVID-19 v Česku: nakažení, úmrtí, testovaní, hospitalizovaní ** Mapa podle okresů, přehled podle věku, situace v Evropě i ve světě ** Každý den aktualizované grafy a mapy

Marek Lutonský | 172

Marek Lutonský
COVID-19Koronavirus
Apple Macbook Air M1: testujeme výkon, výdrž, a hlavně kompatibilitu aplikací [průběžně aktualizováno]

Apple Macbook Air M1: testujeme výkon, výdrž, a hlavně kompatibilitu aplikací [průběžně aktualizováno]

** Testujeme Apple Macbook Air s procesorem M1 ** Zajímá nás nejen výkon, ale zejména kompatibilita aplikací ** Článek je průběžně doplňován na základě vašich dotazů

Jiří Kuruc | 209

Jiří Kuruc
Apple
Google není jen vyhledávač: 15 užitečných funkcí, o kterých možná ani nevíte

Google není jen vyhledávač: 15 užitečných funkcí, o kterých možná ani nevíte

** Google umí kromě vyhledávání i spoustu dalších věcí ** Vybrali jsme více než 15 užitečných funkcí a schopností ** Stačí zadat do vyhledávače ta správná klíčová slova

Karel Kilián | 22

Karel Kilián
TipyVyhledávačeGoogle
Superinteligenci nedokážeme ovládat a nejspíše se nedozvíme, že už tam někde je

Superinteligenci nedokážeme ovládat a nejspíše se nedozvíme, že už tam někde je

** Firmy i organizace včetně EU připravují etické kodexy pro A.I. ** Vědci z Madridu zkoumali, jestli je budeme moci aplikovat na A.I. 2.0 ** A je tu háček, superinteligence pro nás totiž bude neuchopitelná

Jakub Čížek | 84

Jakub Čížek
Umělá inteligence
Výmluvy filmových pirátů jsou stejně ostudné jako český autorský zákon (komentář)

Výmluvy filmových pirátů jsou stejně ostudné jako český autorský zákon (komentář)

** Autorský zákon vůbec nerespektuje internet a současnou realitu. ** Je stahování filmů legální a jaké se na to vztahují výjimky? ** Proč a za co všechno platíme výpalné?

Lukáš Václavík | 361

Lukáš Václavík
PirátstvíHudba, filmy, seriály
Vybíráme nejlepší monitory: Od úplně levných až po displeje na rozmazlování očí

Vybíráme nejlepší monitory: Od úplně levných až po displeje na rozmazlování očí

** Vybrali jsme nejlepší monitory na práci i pořádné hraní ** Nejlevnější monitor s kvalitním panelem nestojí ani tři tisíce ** Rozlišení 4K a větší obrazovka už není nedostupný luxus

David Polesný | 31

David Polesný
Monitory
Japonská MANA může být 80× výkonnější než sebelepší tranzistorový procesor

Japonská MANA může být 80× výkonnější než sebelepší tranzistorový procesor

** Tranzistory současných počítačů vyzařují při přepínání teplo ** Na Tokijské univerzitě proto vyvíjejí adiabatické procesory ** Využívají supravodivost a jsou 80× úspornější

Jakub Čížek | 48

Jakub Čížek
TranzistoryProcesoryTechnologie
Konec modrých obrazovek smrti? Microsoft vydává mimořádnou aktualizaci pro Windows 10
Karel Kilián
Windows UpdateAktualizaceWindows 10

Aktuální číslo časopisu Computer

Megatest rychlých Wi-Fi 6 routerů

Jak ztišit počítač

Velký test mATX skříní