Avatar billede dsj Nybegynder
19. august 2003 - 13:25 Der er 13 kommentarer og
1 løsning

Design-knude (dynamisk nedarvning?)

Jeg er løbet ind i et design-problem med en server, som jeg bare ikke kan finde en løsning på.

Mit problem ville blive løst, hvis man på en eller anden måde kunne lave dynamisk nedarvning, f.eks. gennem class-loading.

Det jeg godt vil have er, at jeg i ét tilfælde vil nedarve fra en bestemt klasse og i et andet tilfælde ønsker at nedarve fra en anden klasse - kan man på nogen måde realisere det!?
Avatar billede jakoba Nybegynder
19. august 2003 - 13:39 #1
definer begge mulige klasser, og så:

Object dinRef = ( defingelse )
                ?  new KlasseDerArverFraVenstre()
                :  new KlasseDerArverFraKonservative();

men det er nok for simpelt er svar til at være det du søger.
Avatar billede jakoba Nybegynder
19. august 2003 - 13:39 #2
Ups.  defingelse  skulle være  betingelse
Avatar billede dsj Nybegynder
19. august 2003 - 13:50 #3
Jow...

Nævnte server består af en master og en slave, der begge har en klient-abstraktion som begge nedarver fra en fælles klient-abstraktion - et lille arve-hierarki:

shared.net.Client <- master.net.Client
shared.net.Client <- slave.net.Client

Problemet er, at der er endnu et lag ovenpå (nævnte er et framework der anvendes af en egentlig applikation), hvor den nederst klient-abstraktion ikke er kendt på kompileringstidspunktet og derfor indlæses med Class.newInstance.

Det jeg godt vil er (angives i serverens konfigurationsfil) at "lave om på" den øverste abstraktion: shared.net.Client, altså overskrive nogle metoder.

Det ville jeg meget gerne gøre ved at lave en ny klasse der nedarver fra shared.net.Client:

shared.net.Client <- shared.net.StreamClient

Det betyder at master.net.Client og slave.net.Client i nogle tilfælde skal nedarve fra shared.net.StreamClient og andre gange fra shared.net.Client.

Da 'extends' jo anvendes på kompileringstidspunktet er problemet lidt kringlet. Det jeg leder efter kunne evt. være et workaround der IKKE indbefatter at ens kode skal skrives to steder.
Avatar billede conrad Nybegynder
19. august 2003 - 14:43 #4
Avatar billede arne_v Ekspert
19. august 2003 - 14:57 #5
Ideelt set tror jeg at du skulle redesigne hele klasse strukturen.

Men mere praktisk (det skulle jo formentligt have været klar i
forgårs - sådan plejer det at være), så måske noget a la:

shared.net.Client
  shared.net.ClientFlavour
      master.net.Client
          master.net.ClientNoStream
          master.net.ClientStream
      slave.net.Client
          slave.net.ClientNoStream
          slave.net.ClientStream

shared.net.ClientFlavour indeholder:

abstract protected boolean isStream();
public void dosomething1() {
  if(isStream()) {
      // do something special
  } else {
      super.dosomething();
  }
}

master.net.ClientNoStream + slave.net.ClientNoStream indeholder:

protected boolean isStream() {
    return false;
}

master.net.ClientStream + slave.net.ClientStream indeholder:

protected boolean isStream() {
    return true;
}

Ikke vildt kønt. Men det burde virke !
Avatar billede dsj Nybegynder
19. august 2003 - 15:43 #6
Hele humlen er, at den samme kode ikke virker både på Windows og Linux. På Windows er jeg nødt til at anvende en outputstream til skrivning af data, mens jeg anvender en SocketChannel under Linux. Dette behov kan blive dækket ved at på Windows at overskrive 2 metoder.

Det angives i serverens konfigurationsfil om der skal køres normalt (med SocketChannel) eller med en outputstream. Hvis jeg forstår dig helt ret arne, skal den spørge til en status-variabel og derudfra bestemme hvilken metode der skal afvikles. Den løsning bryder jeg mig bare ikke særlig meget om. Metoden skal køres rigtig tit (flere gange i sekundet) for hver enkelt klient, og jeg vil derfor godt spare if-sætningen væk. Det jeg var ude efter var i stedet at få fastsat hvilken kode der skal køres idet klienten connecter og Client-objektet oprettes.

I denne forbindelse hælder jeg nok til Strategy Pattern, som conrad foreslår. Jeg fandt et rigtig godt stykke om det her:

http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/StrategyPattern.htm

Hvis et redesign af min klassestruktur løsete problemet gjorde jeg gerne det (og jo, det skulle være færdig i fredags, men jeg er stadig den der er længst fremme :) ). Jeg kan bare ikke se hvordan problemet kan løses uden redundant kode - hvilket det SKAL.
Avatar billede dsj Nybegynder
19. august 2003 - 15:46 #7
Til yderligere information er serveren bygget således at al kode der afvikles i forbindelse med håndteringen af klienter er placeret i Client-klasserne (der nedarver hinanden) hvilket gør, at Worker-trådene ikke indeholder situations-specifik kode og dermed kan bruges i mange sammenhænge.
Avatar billede arne_v Ekspert
19. august 2003 - 15:58 #8
Nu burde det tage langt under en millionte del sekund at lave den if,
så det ville ikke bekymre mig.

Hvis du har tid til at omskrive koden, så er det absolut anbefalelses-værdigt.
Avatar billede dsj Nybegynder
19. august 2003 - 16:02 #9
Jeg har bare ikke nogen bedre design-forslag selv :) andet end at bruge Strategy Pattern.

Har du nogen - er der noget specielt du tænker på?
Avatar billede arne_v Ekspert
19. august 2003 - 16:10 #10
Det grundliggende problem er at du har koblet high-level client logik
med low-level transport logik.

Du bør splitte dem ad.

Eksempel:

shared.net.Client
  master.net.Client
  slave.net.Client

shared.net.Transport
  shared.net.TransportNoStream
  shared.net.TransportStream

Og hvis al client kode bare opererer på en shared.net.Transport, så kan
client koden fodres med en shared.net.TransportNoStream eller
shared.net.TransportStream efter behag.

Dette er i realiteten en 3/4 strategy pattern.

Der mangler kun context. Den mener jeg imidlertid ikke at du behøver idet
dens funktion er at gøre det muligt at skifte strategy midtvejs.
Avatar billede arne_v Ekspert
19. august 2003 - 16:13 #11
Avatar billede dsj Nybegynder
19. august 2003 - 16:15 #12
Ohhhh

Det vil jeg arbejde på - flere gode ideer nu du er i gang!?
Avatar billede arne_v Ekspert
19. august 2003 - 16:37 #13
Ikke lige umiddelbart.
Avatar billede dsj Nybegynder
19. august 2003 - 16:43 #14
Jeg siger i hvert fald tak :)
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