Ferdizz Skrevet 29. mars 2015 Del Skrevet 29. mars 2015 (endret) Hei! Har en oppgave der vi skal lage et program i Java for et bilutleieselskap. All data skal lagres i en PostgreSQL database via JPA og EclipseLink. Har laget en testklasse hvor jeg fint får tilgang (lest og skrevet) til databasen, men er veldig usikker på hvordan jeg skal gå fram når jeg skal få hele det "store" bilutleie-programmet til å fungere opp mot databasen. Fra et tidligere eksempel så ble det brukt en Controller-klasse som "Styrer meldingsflyt mellom brukergrensesnitt og modell ". Slik jeg har forstått det, så skal alle de "vanlige" klassene (Kunde.java, Bil.java osv.) sammen med main/klient-klassene (Kunde_klient.java, Admin_klient.java osv.), hvor da database-kommunikasjonen skjer i main/klient-klassene? Hvordan skal jeg isåfall gå fram for å koble eller "styre meldingsflyten" mellom brukergrensesnitt (main/klient-klassene?) og modell via en Controller-klasse? Jeg kan laste opp dette tidligere eksempelet som bruker en Controller-klasse hvis noen ønsker det. Anyone? Endret 29. mars 2015 av Ferdizz Lenke til kommentar
Enthroner Skrevet 29. mars 2015 Del Skrevet 29. mars 2015 Designmønsteret du skisserer heter Model View Controller og her er en av top google treff på MVC java. Tenk på det slik: Du har en klasse som tar i mot instruksjoner fra brukeren, og presenterer informasjon, denne kan du kalle Kunde_klient.java. Dette er applikasjonen din, og skal ikke inneholde mye kode, jeg vil si at den bør opprette grafisk grensesnitt (bare et vindu, ikke innholdet - om du skal ha GUI) og opprette en Controller. Initialiser programmet ved å kalle en funksjon på Controller, f.eks hjem(); Klienten har til en hver tid et View og denne kan produsere hendelser, f.eks ved at en bruker klikker på en knapp. Slike eventer skal alltid sendes videre til en Controller Du har en (eller fler) klasse® som tar imot instruksjoner fra klienten via det Viewet brukeren ser (og de knappene og andre grensesnitt som er i det). Dette er en Controller. Jeg slang sammen noe fra hodet nå, helt utestet og det er lenge siden jeg har skrevet java, men se om du får noe ut av det: public static void main(String []args){ // opprett en klient, admin eller normal App app = new App(); } public static class App { public App() { // start appen i en 'kjent' tilstand // her starter jeg den i 'hjem' tilstand // så jeg lager en kontroller som vet hvordan man gjør dette // og forteller den at den skal vise hjem(); HeiController controller = new HeiController(this); controller.hjem(); } // dette er hva kontrollere bruker for å kunne vise noe til brukeren public void setView(View view) { this.view = view; this.view.show(); } private View view; } public class HeiController { // en kontroller må vite hvordan man kan vise et View // for å vise view må vi ha tilgang til App public HeiController(App app) { this.app = app; } public void hjem() { // views trenger som regel tilgang til en eller flere kontrollere // for små apper mener jeg det er greit å sende de i konstruktøren app.setView(new KlikkView(this)); } public void ferdig() { app.setView(new FerdigView(this)); } public String getRelevantData() { // bruk modellene dine til å hente data, f.eks // ArrayList<Bil> biler = Bil.hentAlle(); return "Klikk enter!"; } public String getAnnenRelevantData() { // bruk modellene dine til å hente data, f.eks // ArrayList<Bil> biler = Bil.hentAlle(); return "Klikk enter!"; } private App app; } public interface View { void show(); // alle Views må kunne vises til brukeren } public class KlikkView implements View { public KlikkView(HeiController controller) { this.controller = controller; } public void show() { // et veldig enkelt view // printer data som hentes fra controller // ber brukeren om å gjøre noe // forteller controller når noe er gjort System.out.println(controller.getRelevantData()); System.in.read(); controller.ferdig(); } private HeiController controller; } public class FerdigView implements View { public FerdigView(HeiController controller) { this.controller = controller; } public void show() { System.out.println(controller.getAnnenRelevantData()); } private HeiController controller; } Lenke til kommentar
Ferdizz Skrevet 30. mars 2015 Forfatter Del Skrevet 30. mars 2015 (endret) Designmønsteret du skisserer heter Model View Controller og her er en av top google treff på MVC java. Tenk på det slik: Du har en klasse som tar i mot instruksjoner fra brukeren, og presenterer informasjon, denne kan du kalle Kunde_klient.java. Dette er applikasjonen din, og skal ikke inneholde mye kode, jeg vil si at den bør opprette grafisk grensesnitt (bare et vindu, ikke innholdet - om du skal ha GUI) og opprette en Controller. Initialiser programmet ved å kalle en funksjon på Controller, f.eks hjem(); Klienten har til en hver tid et View og denne kan produsere hendelser, f.eks ved at en bruker klikker på en knapp. Slike eventer skal alltid sendes videre til en Controller Du har en (eller fler) klasse® som tar imot instruksjoner fra klienten via det Viewet brukeren ser (og de knappene og andre grensesnitt som er i det). Dette er en Controller. Så hvis det f.eks skal legges til en ny kunde i databasen, så må kunde oppgi litt diverse info som brukes til å opprette et nytt Kunde-objekt som blir brukt videre i en leggTilKunde(Kunde)-metode. Skal/bør da innlesing av input fra bruker og selve opprettelsen av Kunde-objektet skje i Controller-klassen? Og den nødvendige koden for å koble til databasen osv. bør også ligge der? Selv har jeg brukt main/klient-klassen til å "samle sammen" resten av klassene og laget noen få/enkle metoder som tar seg av input, oppretter objekter (f.eks ny Kunde) og kaller på ulike metoder fra resten av klassene (via en enkel tekstbasert meny). Er dette mer kode enn man burde ha i klienten? Her er kunde_klient-klassen min uten bruk av Controller-klasse (sikkert mye dårlig kode der): package no.hib.dat101.klient; import java.util.Scanner; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import no.hib.dat101.Adresse; import no.hib.dat101.Bilutleieselskap; import no.hib.dat101.Kunde; public class Kunde_klient { private static Scanner input = new Scanner(System.in); private static Bilutleieselskap bilselskap = new Bilutleieselskap(); private static Kunde aktuellKunde; // DB-stuff private static EntityManagerFactory factory; private static EntityManager em; private static Query q; public static void main(String[] args) { // More DB-stuff factory = Persistence.createEntityManagerFactory("eclipselink"); em = factory.createEntityManager(); boolean fortsett = false; int valg = 0; do { System.out.println("Meny - Logg inn/ny bruker"); System.out.println("-------------------------"); System.out.println("1) Logg inn"); System.out.println("2) Lag ny bruker"); System.out.print("Valg: "); valg = Integer.parseInt(input.nextLine()); if (valg == 1) { loggInn(); fortsett = true; } else if (valg == 2) { nyKunde(); fortsett = true; } else { System.out.println("Ugyldig valg!"); } } while (!fortsett); // Fortsetter til enten laget ny bruker eller logget inn do { // Hovedmeny for innlogget bruker System.out.println("Meny - Logg inn/ny bruker"); System.out.println("-------------------------"); System.out.println("1) Søk etter bil"); System.out.println("2) Reserver bil"); System.out.print("Valg: "); valg = Integer.parseInt(input.nextLine()); switch (valg) { case 1: sokBil(); break; case 2: reserverBil(); break; default: break; } } while (valg != 9); } public static void nyKunde() { System.out.println("Vennligst fyll inn følgende info..."); System.out.print("Fornavn: "); String fornavn = input.nextLine(); System.out.print("Etternavn: "); String etternavn = input.nextLine(); System.out.print("Postnummer: "); int postNr = Integer.parseInt(input.nextLine()); System.out.print("Poststed: "); String postSted = input.nextLine(); System.out.print("Gateadresse: "); String gate = input.nextLine(); System.out.print("Telefonnummer:"); int tlfNr = Integer.parseInt(input.nextLine()); System.out.print("Kredittkortnummer: "); int kredittKortNr = Integer.parseInt(input.nextLine()); System.out.print("Nytt passord: "); String passord = input.nextLine(); Adresse adresse = new Adresse(gate, postNr, postSted); Kunde kunde = new Kunde(fornavn, etternavn, adresse, tlfNr, kredittKortNr, passord); bilselskap.leggTilKunde(kunde); System.out.println("\nNy bruker opprettet! Brukernavn er: \"" + kunde.getBrukernavn() + "\"."); aktuellKunde = kunde; } public static void loggInn() { boolean funnet = false; boolean rettPass = false; Kunde kunde = null; do { System.out.print("Skriv inn ditt brukernavn: "); String brukernavn = input.nextLine(); kunde = bilselskap.finnKunde(brukernavn); if (kunde == null) { System.out.println("Finner ingen eksisterende kunder med oppgitt brukernavn!"); } else { funnet = true; } } while (!funnet); if (kunde != null) { do { System.out.print("Skriv inn ditt passord: "); String passord = input.nextLine(); if (passord.equals(kunde.getPassord())) { rettPass = true; aktuellKunde = kunde; }else{ System.out.println("Feil passord!"); } } while (!rettPass); } } public static void sokBil() { // TODO } public static void reserverBil() { // TODO } } Takk for informativt svar btw! Endret 30. mars 2015 av Ferdizz Lenke til kommentar
Enthroner Skrevet 30. mars 2015 Del Skrevet 30. mars 2015 Neida, dette er ikke dårlig Spesielt ikke når jeg ser "dat101" i pakkenavnet For å få dette ennå bedre kan du gjøre noen enkle grep og refakturere klassen din litt. Lag en kontroller, og flytt all logikk for database inn i denne. Så i stede for å gjøre // DB-stuff private static EntityManagerFactory factory; private static EntityManager em; private static Query q; Kan du gjøre, private static BilutleieKontroller kontroller; Flytt alle databaseoperasjoner til denne klassen. Det ser også ut som om de vil at du skal spørre Kontroller om data. F.eks Bilutleieselskap bilutleie = kontroller.hentBilutleieselskap(0); Når du vil lagre et object bør det da også sendes til kontrolleren, f.eks til en lagreBil(bil) metode. Hver gang du skal hente et objekt fra databasen så bruker du kontrolleren Hver gang du vil lagre noe til databasen så sender du det til kontrolleren Forøvrig så er dette et annet designmønster som heter Repository Pattern Lenke til kommentar
Ferdizz Skrevet 31. mars 2015 Forfatter Del Skrevet 31. mars 2015 (endret) Sweet! Da skal jeg få til resten Har btw aldri fulgt noe spesielt designmønster tidligere, men antar dette er noe man bør venne seg til? Hvordan går man fram når man skal velge hvilket designmønster som skal brukes? Takk for svar og kjekt at du syns koden ser grei ut! Endret 31. mars 2015 av Ferdizz Lenke til kommentar
Enthroner Skrevet 1. april 2015 Del Skrevet 1. april 2015 Det du burde gjøre mtp designmønstre, hvis du er interessert, er å lese litt om de. Når du skal lage et program så burde du tenke litt, kanskje skrive litt kode, og så se om det passer inn i noe. Hvordan du kan bryte noe ned i et eller flere designmønstre. Å velge designmønster først er ofte en dum ting å gjøre med mindre oppgaven er å gjøre nettop det. tl;dr Tilpass designmønsteret til programmet, ikke programmet til designmønsteret. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå