Avatar billede coolfisk Nybegynder
24. august 2004 - 15:57 Der er 38 kommentarer og
1 løsning

java Composite pattern

Skal lave et program, hvor man kan oprette en opgave. Denne opgave kan have underopgaver, som høre til hovedopgaven. Til dette kan man bruge composite pattern. Hvilket vil sige at klassen kan have chrilds. Nogen der kan vi et eksempel, hvordan man anvender dette pattern, hvor opgaven skal have et navn, og person... disse data skal gemmes i en database.
Avatar billede arne_v Ekspert
24. august 2004 - 16:05 #1
Composite pattern i Java må vel være noget a la:

abstract public class Component {
    ...
    abstract public void dosomething();
    ...
}

public class Leaf extends Component {
    ...
    public void dosomething() {
        ...
    }
    ...
}

public class Composite extends Component {
    ...
    private ArrayList components;
    ...
    public void dosomething() {
        for(int i = 0; i < components.size(); i++) {
            Component c = (Component)components.get(i);
            c.dosomething();
        }
    }
    ...
}
Avatar billede coolfisk Nybegynder
24. august 2004 - 16:07 #2
ja men der skal jo ikke være en abstrakt klasse, da det er den samme opgave der kan blive til underopgave...
Avatar billede coolfisk Nybegynder
24. august 2004 - 16:08 #3
kan du ikke vise et eksempel, hvor man kan add en opgave (eller ligende) til sig selv
Avatar billede arne_v Ekspert
24. august 2004 - 16:09 #4
Du siger at leafs kan blive til composites ?
Avatar billede arne_v Ekspert
24. august 2004 - 16:11 #5
Nej. Det kan composite pattern så vidt jeg ved ikke. Et objekt er enten
et leaf eller en composite, men kan ikke skifte fra den ene til den anden.
Avatar billede coolfisk Nybegynder
24. august 2004 - 16:17 #6
hmmm tror vi snakker forbi hinanden.... Normalt gør composite så man kan have en abstract klasse, f.eks. figur, hvorså man kan anvende composite til at nedarve til underklasser trekant, firkant.... det jeg vil er så jeg har hovedklassen Opgave, og der kan tilføjes(add) en Opgave af samme slags til hovedklassen? Ved ikke om du forstår hvad jeg mener?
Avatar billede coolfisk Nybegynder
24. august 2004 - 16:41 #7
Hvordan ville du skrive det hvis klassen Opgave.java er abstract og man så kan oprette en tysk og en fransk opgave. Men i den tyske opgave er der også fransk, så der skal også oprettes en fransk i den tyske. I main skal man kunne få udskrevet hvilke opgaver der er oprette og hvor mange.

Det kan ende som et stamtræ:

        Tysk
          l
        Fransk
        l    l
      tysk  Fransk
Avatar billede arne_v Ekspert
24. august 2004 - 16:58 #8
Du mener noget ligesom dette:

abstract public class Opgave {
    private Opgave parent;
    private ArrayList childs;
    public void addChild(Opgave opg) {
        childs.add(opg);
    }
    ...
}

public class XxxxOpgave extends Opgave {
    ...
}
Avatar billede coolfisk Nybegynder
24. august 2004 - 17:08 #9
ja noget ligende... har du en opgave eller kan du lave et eks? ...
Avatar billede arne_v Ekspert
24. august 2004 - 17:09 #10
Jeg kan godt lave et eksempel
Avatar billede arne_v Ekspert
24. august 2004 - 18:53 #11
Her er noget der måske ligner:

package opgave;

import java.util.*;

abstract public class Question {
    private String name;
    private ArrayList childs;
    public Question(String name) {
        this.name = name;
        childs = new ArrayList();
    }
    public void addChild(Question q) {
        childs.add(q);
    }
    public void print() {
        print("");
    }
    public void print(String ind) {
        System.out.println(ind + name);
        for(int i = 0; i < childs.size(); i++) {
            Question q = (Question)childs.get(i);
            q.print(ind + "  ");
        }
    }
}

package opgave;

public class GermanQuestion extends Question {
    public GermanQuestion(String s) {
        super("German: " + s);
    }
}

package opgave;

public class FrenchQuestion extends Question {
    public FrenchQuestion(String s) {
        super("French: " + s);
    }
}

package opgave;

public class Test {
    public static void main(String[] args) {
        GermanQuestion ein = new GermanQuestion("ein");
        FrenchQuestion une = new FrenchQuestion("une");
        ein.addChild(une);
        GermanQuestion zwei = new GermanQuestion("zwei");
        FrenchQuestion deux = new FrenchQuestion("deux");
        une.addChild(zwei);
        une.addChild(deux);
        ein.print();
    }
}
Avatar billede arne_v Ekspert
24. august 2004 - 21:50 #12
Hvis du undrer dig over det print og indent, så er det fordi jeg forsøger
at simulere træ strukturen.

Output:

German: ein
  French: une
    German: zwei
    French: deux
Avatar billede arne_v Ekspert
24. august 2004 - 21:52 #13
Men vi er ret langt fra GoF composite pattern.
Avatar billede arne_v Ekspert
24. august 2004 - 21:52 #14
OK ?
Avatar billede coolfisk Nybegynder
26. august 2004 - 14:49 #15
Hvordan ville du lave det i JSP, så man tilføje en tyskopgave og derefter tilføjer en frask under tyskopgaven? Hvordan vil jsp siden se ud? Og hvordan vil man kunne hente opgaven, senere hen? Gemme det i en database?
Avatar billede arne_v Ekspert
26. august 2004 - 15:01 #16
Det vil enten skulles gemmes i en database eller f.eks. i en XML fil.

Umiddelbart vil jeg tro at database er godt.

Den rå funktionalitet er ikke anderledes fordi det er JSP.

Spørgsmålet er så hvordan man laver et fornuftigt bruger interface.

Den vil jeg lige tænke lidt over.
Avatar billede coolfisk Nybegynder
26. august 2004 - 21:11 #17
Hvordan skal man gemme det i en database, så man igen kan hente den enkelte opgave med underopgave? og endda tilføje nye underopgaver...Har du nogle ideer?
Avatar billede arne_v Ekspert
26. august 2004 - 21:13 #18
Du skal bare have en tabel med:

id
parentid
alle de øvrige felter

så kan du hægte dem sammen via parentid->id.
Avatar billede arne_v Ekspert
26. august 2004 - 22:47 #19
Du må så finde ud af om du vil udføre multiple SELECT sætninger (en for hver node
til at finde childs).

Eller du vil lave en neklet SELECT læse op i memory og sammenknytte der.
Avatar billede coolfisk Nybegynder
28. august 2004 - 11:53 #20
parentid skal det hængtes til hovedid eller den chrild den kommer fra?

hovedopgaven har to opgaver... og den ene child har et child:
hovedopgave Tysk - id = 1 parentid = 0
chrild(til hovedopgaven) Fransk - id = 11 parentid = 1
chrild(til hovedopgaven) Dansk - id = 12 parentid = 1
child(til Dansk)Engelsk - id = 121 parentid = 12

Hvordan ville du søge gennemdatabasen for at udskrive hele chrild Dansk

hvis du kan lave et eksempel med det, så ville det være storartet.... og du kan få 80 point for det...
Avatar billede arne_v Ekspert
28. august 2004 - 12:56 #21
Vi er meget langt fra udgangs punktet.

Min første ide er følgende:

tabel Question
--------------

ID    ParentID    Name
1    0    Tysk
11    1    Fransk
12    1    Dansk
121    12    Engelsk

q.jsp
-----

<%@page import="java.sql.*"%>

<%!
    public static String process(String indent, int parentid) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ParentID = " + parentid);
        while(rs.next()) {
            res = res + indent + rs.getString("Name") + "\r\n";
            res = res + process(indent + "    ", rs.getInt("ID"));
        }
        stmt.close();
        con.close();
        return res;
    }
%>
Opgaver:
<pre>
<%=process("", 0)%>
</pre>
Avatar billede coolfisk Nybegynder
28. august 2004 - 13:18 #22
hvad er indent i denne sammenhæng?
Avatar billede arne_v Ekspert
28. august 2004 - 14:00 #23
Præsentationen.

I mangel af bedre ideer har jg bruge PRE tag og indrykning for at markere
strukturen.
Avatar billede arne_v Ekspert
28. august 2004 - 15:04 #24
En lidt mere HTML'ish variant med OL og LI tags:

<%@page import="java.sql.*"%>

<%!
    public static String process(int parentid) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ParentID = " + parentid);
        res = res + "<ol>\r\n";
        while(rs.next()) {
            res = res + "<li>" + rs.getString("Name") + "</li>\r\n";
            res = res + process(rs.getInt("ID"));
        }
        res = res + "</ol>\r\n";
        stmt.close();
        con.close();
        if(!res.equals("<ol>\r\n</ol>\r\n")) {
            return res;
        } else {
            return "";
        }
    }
%>
Opgaver:
<%=process(0)%>
Avatar billede coolfisk Nybegynder
28. august 2004 - 15:15 #25
hvordan vil du lave mainen som kører funktionen process, når det er exceptions?
Avatar billede coolfisk Nybegynder
28. august 2004 - 15:24 #26
eller rettere sagt jsp side
Avatar billede arne_v Ekspert
28. august 2004 - 15:48 #27
Hm.

Måske noget a la:

<%!
public static String process(int parentid) {
  try {
      ...
  } catch (Exception ex) {
      return "Beklager en uforudset fejl skete. Prøv igen og hvis det fortsætter kontakt of.";
  }
}
%>
Avatar billede coolfisk Nybegynder
28. august 2004 - 17:18 #28
nej tænkte at når man vil sende en parentId(fra f.eks. test.jsp) til funktionen, så skal man jo kalde funktionen fra q.jsp....
test.jsp

kald funktion process med værdien 1 = process(1)
Avatar billede coolfisk Nybegynder
28. august 2004 - 17:19 #29
bare så det virker sammen
Avatar billede arne_v Ekspert
28. august 2004 - 17:22 #30
Nu er jeg fuldkommen forvirret.

Ovenstående er 2 komplette JSP sider der kører.

<%!  %>  er ikek så meget brugt og måske var det tænere at smide den ud i en
seperat klasse, men jeg ville forsøge at holde det så simpelt som muligt.
Avatar billede coolfisk Nybegynder
28. august 2004 - 17:23 #31
det skal bare være din q.jsp og en test.jsp hvor du kalder funktionen i q.jsp med en parameter
Avatar billede arne_v Ekspert
28. august 2004 - 17:42 #32
Så skal de lige laves lidt om.
Avatar billede arne_v Ekspert
28. august 2004 - 17:42 #33
<%@page import="java.sql.*"%>

<%!
    public static String process(String indent, int parentid) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ParentID = " + parentid);
        while(rs.next()) {
            res = res + indent + rs.getString("Name") + "\r\n" + process(indent + "    ", rs.getInt("ID"));
        }
        stmt.close();
        con.close();
        return res;
    }
    public static String processfirst(int id) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ID = " + id);
        if(rs.next()) {
            res = rs.getString("Name") + "\r\n" + process("    ", id);
        }
        stmt.close();
        con.close();
        return res;
    }
%>
Opgaver:
<pre>
<%=processfirst(Integer.parseInt(request.getParameter("id")))%>
</pre>
Avatar billede arne_v Ekspert
28. august 2004 - 17:43 #34
<%@page import="java.sql.*"%>

<%!
    public static String process(int parentid) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ParentID = " + parentid);
        res = res + "<ol>\r\n";
        while(rs.next()) {
            res = res + "<li>" + rs.getString("Name") + "</li>\r\n" + process(rs.getInt("ID"));
        }
        res = res + "</ol>\r\n";
        stmt.close();
        con.close();
        if(!res.equals("<ol>\r\n</ol>\r\n")) {
            return res;
        } else {
            return "";
        }
    }
    public static String processfirst(int id) throws Exception {
        String res = "";
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection con = DriverManager.getConnection("jdbc:odbc:;Driver={Microsoft Access Driver (*.mdb)};Dbq=D:\\Database\\MSAccess\\Test.mdb;Uid=Admin;Pwd=;");
        Statement stmt = con.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM Question WHERE ID = " + id);
        if(rs.next()) {
            res = "<ol>\r\n<li>" + rs.getString("Name") + "</li>\r\n" + process(id) + "</ol>\r\n";
        }
        stmt.close();
        con.close();
        return res;
    }
%>
Opgaver:
<%=processfirst(Integer.parseInt(request.getParameter("id")))%>
Avatar billede coolfisk Nybegynder
28. august 2004 - 17:45 #35
"int id" og "int parentId" skal sættes fra en anden jsp siden... det er bare den side jeg ville have dig til at lave.... Ved ikke om du forstår hvad jeg mener??
Avatar billede arne_v Ekspert
28. august 2004 - 17:48 #36
Fast:

<a href="q.jsp?id=1">go</a>

Angives:

<form method="post" action="q.jsp">
ID: <input type="text" name="id"/>
<br/>
<input type="submit" value="Go"/>
</form>
Avatar billede coolfisk Nybegynder
28. august 2004 - 18:02 #37
ok fedt!!! ... opretter lige et spørgsmål, så du kan få dine point:

java treefordeling

ok?
Avatar billede arne_v Ekspert
28. august 2004 - 18:08 #38
OK
Avatar billede arne_v Ekspert
28. august 2004 - 18:09 #39
Men er du tilfreds med løsningen ?

Det er noget som kan løses på mange måder.
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
Kurser inden for grundlæggende programmering

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