Avatar billede decrypto Nybegynder
07. maj 2005 - 16:00 Der er 20 kommentarer og
1 løsning

interface hvornår og hvorfor?

Jeg har netop siddet og læst afsnittet om interface i c#, men jeg kan ikke rigtig finde ud af, hvornår og hvorfor det er smart.

Er der nogen, der kan opklare dette til mig med et simpelt eksempel og en forklaring på de benefits der er?

Mange tak.
Avatar billede arne_v Ekspert
07. maj 2005 - 16:06 #1
pointen er adskillelse af interface og implementation

et interface = en kontrakt om hvilken service man tilbyder

en class = en bestemt måde at levere den service på

ved at kode mest muligt op mod interfaces er man uafhængig af den
konkrete implementation
Avatar billede arne_v Ekspert
07. maj 2005 - 16:10 #2
Du kan sammenligne det lidt med browser - web server. En browser skal
kun vide at web serveren snakker HTML 4.01 over HTTP 1.1 - den skal ikke
vide om det er en IIS eller en Apache.

Hvis du laver et interface PersistData med en Save og en Load metode, så
kan en applikation bruge interfacet alle steder undtagen ved instantiering
og på den måde ikke vide hvordan data persisteres. Du har måske så 2 implementations
class'es PersistDataDatabase og PersistDataXml og du kan skifte mellem dem
udelukkende ved at ændre instantieringen.
Avatar billede decrypto Nybegynder
07. maj 2005 - 16:18 #3
Hvis man har delt koden op i 3 lag el. flere er det så ikke fint nok uden at have interfaces?

Jeg har fx. et par klasser, der hver især indeholder hent-opdater/indsæt data. Kunne det så tænkes at jeg havde 2 stk interfaces for hver klasse IRead, ISave ?

Har du et eksempel på lidt simpelt kode  med interfaces?
Avatar billede arne_v Ekspert
07. maj 2005 - 16:20 #4
opdeling i lag efter funktion og opdeling i interface og implementation
er 2 helt forskellige ting

du bør lave et interface hvis du kan forestille dig at du senere vil
ændre implementationen
Avatar billede arne_v Ekspert
07. maj 2005 - 16:22 #5
using System;

public interface AnyC
{
    void doit();
}

public class C1 : AnyC
{
    public void doit()
    {
        Console.WriteLine("I am a 1");
    }
}

public class C2 : AnyC
{
    public void doit()
    {
        Console.WriteLine("I am a 2");
    }
}

public class Tester
{
    private AnyC c;
    public Tester(AnyC c)
    {
        this.c = c;
    }
    public void test()
    {
        c.doit();
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        Tester t1 = new Tester(new C1());
        t1.test();
        Tester t2 = new Tester(new C2());
        t2.test();
    }
}
Avatar billede decrypto Nybegynder
07. maj 2005 - 16:53 #6
all right send bare et svar ind....jeg kigger på det iaften.
Avatar billede spif2001 Nybegynder
07. maj 2005 - 16:59 #7
En extra lækker ting er, når man bruger interfacet som type. Givet Arnev's kode:

public class BussinessLayer
{
  private AnyC myHandler;

  public BussinessLayer(AnyC handler)
  {
      this.myHandler = handler;
  }//constructor

  public DoItMyWay()
  {
      this.myHandler.doit()
  }
}

Her kan man f.eks. ændre hvilken databaseconnection man vil bruge under runtime...
Avatar billede lanstorp Nybegynder
07. maj 2005 - 17:10 #8
Jeg har skrevet en artikel om interfaces i C#, der kan findes på:
http://www.codeproject.com/csharp/InterfaceConstruct.asp
Avatar billede arne_v Ekspert
07. maj 2005 - 17:20 #9
svar
Avatar billede spif2001 Nybegynder
07. maj 2005 - 17:37 #10
lanstorp --> lækker lille artikel der ;)
Avatar billede decrypto Nybegynder
07. maj 2005 - 17:43 #11
Tak for artiklen.
Avatar billede lanstorp Nybegynder
07. maj 2005 - 18:02 #12
Er selv meget glad for interfaces. Konstruktionen er nok noget undervuderet i den daglige programmering. Som værktøj, til at dekoble ens design og gøre det fleksibelt for fremtidige ændringer, er det sagen.
Avatar billede arne_v Ekspert
07. maj 2005 - 19:15 #13
afhænger nok lidt af hvilken baggrund folk har

folk med Java baggrund vil formentligt have nemt ved at bruge
interfaces (Java API bruger interfaces meget mere end .NET API - f.eks.
består database og XML API'erne i Java stort set kun af interfaces)

ligeledes vil folk med COM baggrund nok også have meget nemt ved
interfaces

VB6, Delphi og "C++ er da bare C med erklæringer hvor som helst og // kommentarer"
folk skal nok vende sig lidt til konstruktionen
Avatar billede decrypto Nybegynder
07. maj 2005 - 21:23 #14
Giver nedenstående mening? Koden bliver kompileret fint og uden fejl. Jeg er bare ikke sikker på at jeg gør det rigtigt eller hvad?

----------------------- Kode ---------------------
using System;
using System.Collections;
using MySql;
using MySql.Data;
using MySql.Data.MySqlClient;
using wwwbutikdk.businessLogicLayer;

namespace wwwbutikdk.dataAccessLayer
{
    // Interface
    interface IStorable{
        void SaveProduct(ProductEntity p);
    }

    /// <summary>
    /// Summary description for Product.
    /// </summary>
    public class ProductDALC : IStorable
    {
        // Constuctor
        public ProductDALC()
        {
        }

   
        public ArrayList GetProductSearchLst(string SoegStreng)
        {
            string SQL = "SELECT product.id AS product_id, product.name AS product_name, product.price AS product_price, photo.id as photo_id, photo.photo_data FROM product INNER JOIN photo ON (product.photo_id = photo.id) WHERE (NAME LIKE '%"+ SoegStreng +"%')ORDER BY NAME;";
   
            DbConnector dbCon = new DbConnector();
            MySqlDataReader rdr = dbCon.DbConnect(SQL);

            ArrayList arrLstProduct = new ArrayList();
               
            while (rdr.Read())
            {
                ProductEntity p = new ProductEntity();
                p.ProductId                            =                (int) rdr["product_id"];
                p.ProductName                        =                (string) rdr["product_name"];
                p.ProductPrice                        =                Convert.ToDecimal(rdr["product_price"]);
                p.ProductPhotoId                    =                (int) rdr["photo_id"];
                arrLstProduct.Add(p);
            }
            dbCon.DbClose();
            return arrLstProduct;
        }

        public ArrayList GetProduct(int ProductId)
        {   
               
            string SQL = "SELECT product.id AS product_id, product.name AS product_name, product.price AS product_price, photo.id as photo_id, product.description as product_description FROM product INNER JOIN photo ON (product.photo_id = photo.id) WHERE product.id = "+ ProductId + "";
            DbConnector dbCon = new DbConnector();
            MySqlDataReader rdr = dbCon.DbConnect(SQL);
               
            ArrayList arrLstProduct = new ArrayList();
               
            if (rdr.Read())
            {
                ProductEntity p = new ProductEntity();
                p.ProductId                            =                (int) rdr["product_id"];
                p.ProductName                        =                (string) rdr["product_name"];
                p.ProductPrice                        =                Convert.ToDecimal(rdr["product_price"]);
                p.ProductPhotoId                    =                (int) rdr["photo_id"];
                p.ProductDescription                =                (string) rdr["product_description"];
                arrLstProduct.Add(p);
            }

            dbCon.DbClose();
            return arrLstProduct;
        }

        public void SaveProduct(ProductEntity p){

            string SQL = "INSERT INTO product(product.photo_id, product.supplier_id, product.name, product.price, product.description) VALUES("+ p.ProductPhotoId +","+ p.SupplierId +",'"+ p.ProductName +"',"+ p.ProductPrice +",'"+ p.ProductDescription +"');";
            DbConnector dbCon = new DbConnector();
            dbCon.DbConnect(SQL);
            dbCon.DbClose();

        }
        }
}

------ implementation --------------
public void SaveProduct(){
           
            ProductEntity p = new ProductEntity();
            p.ProductPhotoId = 2;
            p.SupplierId = 1;
            p.ProductName = "New fasil";
            p.ProductPrice = 299;
            p.ProductDescription = "A little description";

            ProductDALC NewProduct = new ProductDALC();
            NewProduct.SaveProduct(p);
       
        }
Avatar billede arne_v Ekspert
07. maj 2005 - 22:13 #15
det du kalder implementation er ikke implementation men brug

implemtationen er i public class ProductDALC : IStorable
Avatar billede arne_v Ekspert
07. maj 2005 - 22:14 #16
og du bruger jo ikke rigtigt interfacet til noget
Avatar billede arne_v Ekspert
07. maj 2005 - 22:19 #17
public interface IProductDAL {
        ArrayList GetProductSearchLst(string SoegStreng);
        ArrayList GetProduct(int ProductId);
        void SaveProduct(ProductEntity p);
    }

public class ProductDALDatabase : IProductDAL
{
    public ProductDALDatabase(string ConnStreng)
    {
        ...
    }
    public ArrayList GetProductSearchLst(string SoegStreng)
    {
        ...
    }
    public ArrayList GetProduct(int ProductId)
    {
        ...
    }
    public void SaveProduct(ProductEntity p)
    {
        ...
    }
}


public class ProductDALXml : IProductDAL
{
    public ProductDALXml(string FileName)
    {
        ...
    }
    public ArrayList GetProductSearchLst(string SoegStreng)
    {
        ...
    }
    public ArrayList GetProduct(int ProductId)
    {
        ...
    }
    public void SaveProduct(ProductEntity p)
    {
        ...
    }
}

og så:

            //IProductDAL NewProduct = new ProductDALDatabase();
            IProductDAL NewProduct = new ProductDALXml();
            NewProduct.SaveProduct(p);
Avatar billede decrypto Nybegynder
07. maj 2005 - 22:23 #18
Men det er en god ide at have et interface?

Jeg har skrevet lidt om i koden....
Poster lige et eksempel....men de giver fejl.

-------------------------------------
    // Interface
    interface IProduct{

        void Save(ProductEntity p);
        ArrayList GetProductSearchLst(string SoegStreng);
        ArrayList GetProduct(int ProductId);
    }
-----------------------------------------------------

    public class ProductDALC : IProduct
    {
        string SoegStreng;
        int ProductId;
        ProductEntity p;

        // Constuctor
        public ProductDALC()
        {
        }

   
        public ArrayList GetProductSearchLst(string SoegStreng)
        {
            this.SoegStreng = SoegStreng;

            string SQL = "SELECT product.id AS product_id, product.name AS product_name, product.price AS product_price, photo.id as photo_id, photo.photo_data FROM product INNER JOIN photo ON (product.photo_id = photo.id) WHERE (NAME LIKE '%"+ SoegStreng +"%')ORDER BY NAME;";
   
            DbConnector dbCon = new DbConnector();
            MySqlDataReader rdr = dbCon.DbConnect(SQL);

            ArrayList arrLstProduct = new ArrayList();
               
            while (rdr.Read())
            {
                ProductEntity p = new ProductEntity();
                p.ProductId                            =                (int) rdr["product_id"];
                p.ProductName                        =                (string) rdr["product_name"];
                p.ProductPrice                        =                Convert.ToDecimal(rdr["product_price"]);
                p.ProductPhotoId                    =                (int) rdr["photo_id"];
                arrLstProduct.Add(p);
            }
            dbCon.DbClose();
            return arrLstProduct;
        }

        public ArrayList GetProduct(int ProductId)
        {   
            this.ProductId = ProductId;

            string SQL = "SELECT product.id AS product_id, product.name AS product_name, product.price AS product_price, photo.id as photo_id, product.description as product_description FROM product INNER JOIN photo ON (product.photo_id = photo.id) WHERE product.id = "+ ProductId + "";
            DbConnector dbCon = new DbConnector();
            MySqlDataReader rdr = dbCon.DbConnect(SQL);
               
            ArrayList arrLstProduct = new ArrayList();
               
            if (rdr.Read())
            {
                ProductEntity p = new ProductEntity();
                p.ProductId                            =                (int) rdr["product_id"];
                p.ProductName                        =                (string) rdr["product_name"];
                p.ProductPrice                        =                Convert.ToDecimal(rdr["product_price"]);
                p.ProductPhotoId                    =                (int) rdr["photo_id"];
                p.ProductDescription                =                (string) rdr["product_description"];
                arrLstProduct.Add(p);
            }

            dbCon.DbClose();
            return arrLstProduct;
        }

        public void Save(ProductEntity p)
        {
            this.p = p;

            string SQL = "INSERT INTO product(product.photo_id, product.supplier_id, product.name, product.price, product.description) VALUES("+ p.ProductPhotoId +","+ p.SupplierId +",'"+ p.ProductName +"',"+ p.ProductPrice +",'"+ p.ProductDescription +"');";
            DbConnector dbCon = new DbConnector();
            dbCon.DbConnect(SQL);
            dbCon.DbClose();
            Console.WriteLine("Interface");

        }
    }
}
--------------------------------------------------------

Men jeg får 3 fejl...der siger....
Fejl 1:
\productdalc.cs(21): 'wwwbutikdk.dataAccessLayer.ProductDALC' does not implement interface member 'wwwbutikdk.dataAccessLayer.IProduct.GetProduct(int)'. 'wwwbutikdk.dataAccessLayer.ProductDALC.GetProduct(int)' is either static, not public, or has the wrong return type.

Jeg tror jeg denne gang gør brug af interface....men det fejler, hvad overser jeg? Kan du hjælpe?
Avatar billede decrypto Nybegynder
07. maj 2005 - 22:26 #19
ProductEntity p = new ProductEntity();
            p.ProductPhotoId = 2;
            p.SupplierId = 1;
            p.ProductName = "New fasil";
            p.ProductPrice = 299;
            p.ProductDescription = "A little description";

            ProductDALC NewProduct = new ProductDALC();
            NewProduct.Save(p);
Avatar billede decrypto Nybegynder
07. maj 2005 - 22:51 #20
Jeg kan se at jeg har kopieret noget forkert kode ind fejlen opstår, fordi jeg har erklæret fx.

private ArrayList GetProductSearchLst(string SoegStreng)
{
....
}

Det virker hvis jeg erstatter "private" med "public", men hvor kan jeg ikke skrive private, da jeg jo kun skal kommunikere via interfacet?
Avatar billede lanstorp Nybegynder
07. maj 2005 - 23:44 #21
Interface metoder er implicit public, da de skal bruges af andre klasser.

Meningen med det du har lavet er, at du kunne tænke dig, engang i fremtiden, at implementere de tre interface metoder på en anden måde, end du har gjort her. Som i arne v's eksempel 07/05-2005 22:19:02. Prøv at kikke på din driverkode. I arne v's eksempel er det:           
//IProductDAL NewProduct = new ProductDALDatabase();
IProductDAL NewProduct = new ProductDALXml();
NewProduct.SaveProduct(p);

Som det ser ud nu, har du ikke brug for et interface, dvs. at lave den samme ting på forskellige måder. Kan du tænke dig at implementere de tre metoder i interfacet på en anden måde? Hvis ikke, skal du ikke bruge et interface.
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
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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