Avatar billede badal Nybegynder
20. april 2007 - 10:19 Der er 13 kommentarer og
1 løsning

Lagdeling DAL / BLL

Jeg skal til at kode et større applikation og vil gerne benytte lag. Hvilken lag vil I anbefale? Databasen skal kunne udskiftes, uden at påvirke forretningslogikken. Det gør ikke noget hvis der er 2-3 lag. Feks. DAL, BLL, MODEL/VIEW.
Hvordan kan bygge det smartest?
Avatar billede mikkel_sommer Nybegynder
20. april 2007 - 12:24 #1
Jeg ville dele det op i 3 lag:

- GUI
- BLL
- DAL

Derved opnår du at det kun er DAL laget som skal ændres hvis du skifter database. Man kunne godt slå de to andre sammen til et men jeg ville mene at det er forkert at have logik kode i GUI'en.
Avatar billede badal Nybegynder
20. april 2007 - 12:49 #2
har du et link til et site hvor man kan se eksemplel på denne tre lags deling? jeg vil mene at det er bedst med denne 3 lags deling.
Avatar billede mikkel_sommer Nybegynder
20. april 2007 - 13:53 #3
mener du et system som er lavet ud fra det princip?
Avatar billede mikkel_sommer Nybegynder
20. april 2007 - 13:57 #4
Det er faktisk ikke så slemt når først du kommer ind i tankegangen. Du har nogle tabeller i db'en og for hver tabel laver du et DAL objekt med de properties som tabelen har koloner og som indeholder metoder til at gemme, hente, opdatere og slette i denne tabel. Dernæst laver du en BLL klasse hvori du kan manipulere dataen i DAL objektet så det kommer ud i den for du skal bruge i din GUI. Det kunne eksempelvis være at lave lister osv. osv. Og til sidst har du GUIen hvor du kan præsentere data for brugeren og denne kan behandle dataen med den funktionalitet du i BLL laget stiller til rådighed.
Avatar billede arne_v Ekspert
21. april 2007 - 05:17 #5
jeg lavede et super simpelt eksempel i ASP.NET 1.1 til et spørgsmål for et par år siden
Avatar billede arne_v Ekspert
21. april 2007 - 05:17 #6
<%@ Page Inherits="PL.Transfer" %>
<html>
<head>
<title>Money transfer</title>
</head>
<body>
<form id="f" method="post" runat="server">
From account: <asp:TextBox id="fromaccount" runat="server"/>
<br>
To account: <asp:TextBox id="toaccount" runat="server"/>
<br>
Amount: <asp:TextBox id="amount" runat="server"/>
<br>
<asp:Button id="transfer" text="Transfer" runat="server"/>
<br>
<asp:Label id="status" runat="server"/>
</form>
</body>
</html>
Avatar billede arne_v Ekspert
21. april 2007 - 05:18 #7
using System;
using System.Web.UI;
using System.Web.UI.WebControls;

using BLL;

namespace PL
{
    public class Transfer : Page
    {
        protected TextBox fromaccount;
        protected TextBox toaccount;
        protected TextBox amount;
        protected Button transfer;
        protected Label status;
        private TransferManager tm;
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            transfer.Click += new EventHandler(transfer_Click);
            tm = TransferManagerFactory.Create("strict");
        }
        protected void transfer_Click(object sender, EventArgs e)
        {
            if(tm.ExecuteTransfer(new TransferData(fromaccount.Text, toaccount.Text, decimal.Parse(amount.Text))))
            {
                fromaccount.Text = "";
                toaccount.Text = "";
                amount.Text = "";
                status.Text = "Money transferred";
            }
            else
            {
                status.Text = "Money not transferred";
            }
        }
    }
}
Avatar billede arne_v Ekspert
21. april 2007 - 05:18 #8
using System;

using DAL;

namespace BLL
{
    public class TransferData
    {
        private string fromaccount;
        private string toaccount;
        private decimal amount;
        public TransferData() : this("", "", 0.00m)
        {
        }
        public TransferData(string fromaccount, string toaccount, decimal amount)
        {
            this.fromaccount = fromaccount;
            this.toaccount = toaccount;
            this.amount = amount;
        }
        public string Fromaccount
        {
            get
            {
                return fromaccount;
            }
            set
            {
                fromaccount = value;
            }
        }
        public string Toaccount
        {
            get
            {
                return toaccount;
            }
            set
            {
                toaccount = value;
            }
        }
        public decimal Amount
        {
            get
            {
                return amount;
            }
            set
            {
                amount = value;
            }
        }
    }
    public interface TransferManager
    {
        bool ExecuteTransfer(TransferData xfer);
    }
    public class TransferManagerFactory
    {
        public static TransferManager Create(string tmtyp)
        {
            if(tmtyp == "standard")
            {
                return new StandardTransferManager();
            }
            if(tmtyp == "strict")
            {
                return new StrictTransferManager();
            }
            else
            {
                return null;
            }
        }
    }
    internal class StandardTransferManager : TransferManager
    {
        private AccountManager am;
        public StandardTransferManager()
        {
            am = AccountManagerFactory.Create("XML");
        }
        public bool ExecuteTransfer(TransferData xfer)
        {
            AccountData fromaccount = am.Load(xfer.Fromaccount);
            AccountData toaccount = am.Load(xfer.Toaccount);
            if(fromaccount != null && toaccount != null && fromaccount.Amount >= xfer.Amount)
            {
                fromaccount.Amount -= xfer.Amount;
                toaccount.Amount += xfer.Amount;
                am.Save(fromaccount);
                am.Save(toaccount);
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    internal class StrictTransferManager : TransferManager
    {
        private const int TRANSFER_LIMIT = 1000;
        private const int ACCOUNT_LIMIT = 10000;
        private AccountManager am;
        public StrictTransferManager()
        {
            am = AccountManagerFactory.Create("DB");
        }
        public bool ExecuteTransfer(TransferData xfer)
        {
            AccountData fromaccount = am.Load(xfer.Fromaccount);
            AccountData toaccount = am.Load(xfer.Toaccount);
            if(fromaccount != null && toaccount != null && fromaccount.Amount >= xfer.Amount &&
              xfer.Amount <= TRANSFER_LIMIT && (toaccount.Amount + xfer.Amount) <= ACCOUNT_LIMIT)
            {
                fromaccount.Amount -= xfer.Amount;
                toaccount.Amount += xfer.Amount;
                am.Save(fromaccount);
                am.Save(toaccount);
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
Avatar billede arne_v Ekspert
21. april 2007 - 05:19 #9
using System;
using System.IO;
using System.Xml;
using System.Data.OleDb;

namespace DAL
{
    public class AccountData
    {
        private string name;
        private decimal amount;
        public AccountData() : this("", 0.00m)
        {
        }
        public AccountData(string name, decimal amount)
        {
            this.name = name;
            this.amount = amount;
        }
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
        public decimal Amount
        {
            get
            {
                return amount;
            }
            set
            {
                amount = value;
            }
        }
    }
    public interface AccountManager
    {
        AccountData Load(string name);
        void Save(AccountData ac);
    }
    public class AccountManagerFactory
    {
        public static AccountManager Create(string amtyp)
        {
            if(amtyp == "DB")
            {
                return new DatabaseAccountManager();
            }
            if(amtyp == "XML")
            {
                return new XmlAccountManager();
            }
            else
            {
                return null;
            }
        }
    }
    internal class DatabaseAccountManager : AccountManager
    {
        public AccountData Load(string name)
        {
            AccountData res;
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Databases\\MSAccess\\Test.mdb");
            con.Open();
            OleDbCommand sel = new OleDbCommand("SELECT amount FROM accounts WHERE name='" + name + "'", con);
            OleDbDataReader rdr = sel.ExecuteReader();
            if(rdr.Read())
            {
                decimal amount = (decimal)rdr[0];
                res = new AccountData(name, amount);
            }
            else
            {
                res = null;
            }
            con.Close();
            return res;
        }
        public void Save(AccountData ac)
        {
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Databases\\MSAccess\\Test.mdb");
            con.Open();
            OleDbCommand upd = new OleDbCommand("UPDATE accounts SET amount = " + ac.Amount + " WHERE name='" + ac.Name + "'", con);
            upd.ExecuteNonQuery();
        }
    }
    internal class XmlAccountManager : AccountManager
    {
        private const string XML_FILE = @"C:\accounts.xml";
        private XmlDocument doc;
        public XmlAccountManager()
        {
            doc = new XmlDocument();
            doc.Load(XML_FILE);
        }
        public AccountData Load(string name)
        {
            XmlNode n = doc.SelectSingleNode("//accounts/account[@name='" + name +"']");
            if(n != null)
            {
                decimal amount = decimal.Parse(n.Attributes["amount"].Value);
                return new AccountData(name, amount);
            }
            else
            {
                return null;
            }
        }
        public void Save(AccountData ac)
        {
            XmlNode n = doc.SelectSingleNode("//accounts/account[@name='" + ac.Name +"']");
            n.Attributes["amount"].Value = ac.Amount.ToString();
            StreamWriter sw = new StreamWriter(XML_FILE);
            doc.Save(sw);
            sw.Close();
        }
    }
}
Avatar billede badal Nybegynder
21. april 2007 - 12:39 #10
Så det er en "Three-tier architecture" som ekspempelvis kan som vist her på den her link: http://msdn2.microsoft.com/en-us/library/aa581779.aspx
Avatar billede arne_v Ekspert
21. april 2007 - 20:13 #11
det er både en 3 tier (browser, web app, database) og en 3 layer web app (PL, BLL, DAL)
Avatar billede arne_v Ekspert
17. juni 2007 - 05:47 #12
badal ?
Avatar billede badal Nybegynder
17. juni 2007 - 11:55 #13
det er vist tid til at lukke spm. Kan du komme med et svar, arne
Avatar billede arne_v Ekspert
17. juni 2007 - 15:54 #14
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester