/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Abstract singleton class
Fra : Bjarke Walling Peter~


Dato : 22-01-06 01:37

Hej.

Lidt baggrundsviden:

Jeg er ved at lave nogle interfaces, der beskriver hvordan man
low-level tilgår drev på det aktuelle system. De to primære
interfaces er Drives og Drive. Drives implementerer Iterable<Drive>, og
meningen er desuden at det er er en singleton, dvs. man bruger den til
at få en liste over drev på computeren (det være sig harddiske,
CD-Rom, usbdisk, diskette, m.fl.). Drives er altså tilgangen til at
bruge dette framework. Man bruger den klasse til at finde det drev man
ønsker, eller itererer over alle drevene.
Jeg vil adskille interface og implementation, så det er muligt for
andre at lave implementationer til flere platforme, af den grund det
kræver JNI. Selv vil jeg lave en implementation til Windows NT/2k/XP -
og Posix, når jeg finder ud af hvordan.

Min idé er at Drives skal være en abstract class. Den eneste grund er
at jeg kan lave en statisk metode getInstance(). Det er ikke muligt at
lave statiske metoder på et interface. Metoden getInstance()
returnerer en instans af implementationsklassen. Implementationen
bliver i øvrigt fundet ved at kigge på bestemt property, som
indeholder classpath til den klasse der implementerer, dvs. nedarver
Drives. Det er altså muligt at skifte implementation blot ved at
ændre denne property.

Og nu til spørgsmålet:

Jeg synes umiddelbart at en abstract class er den bedste løsning, men
andre forslag modtages gerne. Det der irriterer mig mest er at jeg
skriver 'implements' ved f.eks. DriveImpl-klassen og andre, hvorimod
'DrivesImpl extends Drives'. Måske ville det være mere rigtigt at
lave Drives som et interface, og så lave en klasse, f.eks. Driver
(eller et bedre navn?), der har en statisk getImplementation() metode
som det eneste? Især set i lyset af at ansvaret for Drives klassen
lige nu er to ting: At give det interface, som kan implementeres, samt
at tilbyde en instans af implementationen for brugeren.

Mvh.
Bjarke W.


 
 
Soren Kuula (22-01-2006)
Kommentar
Fra : Soren Kuula


Dato : 22-01-06 06:51

Bjarke Walling Petersen wrote:
> Hej.

Hejsa!

> Lidt baggrundsviden:

....

Du kender godt getRoots, eller hvad den lige hedder, på File, ikke?

> Min idé er at Drives skal være en abstract class. Den eneste grund er
> at jeg kan lave en statisk metode getInstance(). Det er ikke muligt at
> lave statiske metoder på et interface. Metoden getInstance()
> returnerer en instans af implementationsklassen. Implementationen
> bliver i øvrigt fundet ved at kigge på bestemt property, som
> indeholder classpath til den klasse der implementerer, dvs. nedarver
> Drives. Det er altså muligt at skifte implementation blot ved at
> ændre denne property.
>
> Og nu til spørgsmålet:
>
> Jeg synes umiddelbart at en abstract class er den bedste løsning, men
> andre forslag modtages gerne. Det der irriterer mig mest er at jeg
> skriver 'implements' ved f.eks. DriveImpl-klassen og andre, hvorimod
> 'DrivesImpl extends Drives'. Måske ville det være mere rigtigt at
> lave Drives som et interface, og så lave en klasse, f.eks. Driver
> (eller et bedre navn?), der har en statisk getImplementation() metode
> som det eneste? Især set i lyset af at ansvaret for Drives klassen
> lige nu er to ting: At give det interface, som kan implementeres, samt
> at tilbyde en instans af implementationen for brugeren.

Jo det er vist en alm. løsning:

interface Drive {
...
}

interface Drives extends Iterable<Drive> {
...
}

class FileSystems {
static DriveAccessorDims getBootstrap() {...}
}

-- der er jo ikke nogen som tvinger dig til at skrive FileSystems som en
impl. af Drives. Der er heller ikke nogen der tvinger dig dit ikke at
gøre det.


... det bedste praktiske design kommer sjældent ved at jappe det sammen
helt uden at tænke sig om ... men heller ikke ved at tænke alt igennem
til perfektion (det ender tit med noget som ser smart ud, bare fordi det
ikke er set før, men i virkeligheden er kluntet & forvirrende). Men hvis
man tænker sig lidt om fra starten, gætter hvad der er væsentligst, og
så retter til efterhånden (refactoring tools er godt) som de reelle
betingelser og alle forglemmelserne viser sig, så kører det...


En abstrakt klasse kan forresten kun en ting ekstra: Erklære en
ikkestatisk metode (eller _få_ den erklæret ved at implementere et
interface hhv extende in abstrakt klasse), men undlade at implementere
den. Og du kan altid lave en klasse abstrakt -- men må så ikke
instantiere den.


MVH
Søren

Thorbjørn Ravn Ander~ (22-01-2006)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 22-01-06 09:28

Soren Kuula <dongfang@dongfang.dk> writes:

> .. det bedste praktiske design kommer sjældent ved at jappe det sammen
> helt uden at tænke sig om ... men heller ikke ved at tænke alt igennem
> til perfektion (det ender tit med noget som ser smart ud, bare fordi
> det ikke er set før, men i virkeligheden er kluntet &
> forvirrende). Men hvis man tænker sig lidt om fra starten, gætter hvad
> der er væsentligst, og så retter til efterhånden (refactoring tools er
> godt) som de reelle betingelser og alle forglemmelserne viser sig, så
> kører det...

Det kan anbefales at lave den slags med unit tests da man så laver
kode der skal bruge ens kode inden man skriver den faktiske kode. Man
opdager mange uhensigtsmæssigheder på den måde.

Mht implements versus extends så er extends godt til dataklässer men
ellers bruger jeg interfaces. Så er man mest fleksibel.

--
Thorbjørn Ravn Andersen


Bjarke Walling Peter~ (22-01-2006)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 22-01-06 16:21

Tak for dit svar.

Soren Kuula wrote:
> Du kender godt getRoots, eller hvad den lige hedder, på File, ikke?

Jo. File er adgang på filsystem-niveau. Med mit API er det et lavere
niveau man har i tankerne. Følgende skal gerne kunne lade sig gøre,
når jeg færdig:
1) Liste partitioner og typer af filsystem - og om disken overhovedet
understøtter partitioner.
2) Læse MBR/PBR eller skrive, dvs. skifte koden ud i dem.
3) Læse og skrive til "hidden sectors", hvis de findes.
4) Angive en fil og få dens fysiske position på disken, samt om den
er fragmenteret - og i så fald skal man kunne defragmentere lige netop
den fil.
5) Sætte en fil til at være systemfil, dvs. den ikke bliver flyttet
eller skrevet til uden videre.
6) Få et File-objekt der repræsenterer roden af en partition

Selv vil jeg bruge API'et til at lave nogle værktøjer, FStools kalder
jeg dem, og BootConfig. Det sidste skal kunne installere en ny
bootloader/bootmanager på din computer - og hente opdateringer til
den, hvis der er.
Ad punkt 4) og 5) bliver det lidt svært, for det har jeg jo på sin
vis noget med et filsystem at gøre, hvor alle andre metoder ikke har
noget med selve filsystemet (eller filerne) at gøre. Men jeg har
tænkt at man måske kan give et File-objekt som parameter til de filer
man ønsker at operere på. Eller bruge adapter pattern i en
LowlevelFile klasse, der modtager et File-objekt i constructoren.

> Jo det er vist en alm. løsning:
>
> interface Drive {
> ...
> }
>
> interface Drives extends Iterable<Drive> {
> ...
> }
>
> class FileSystems {
> static DriveAccessorDims getBootstrap() {...}
> }
>
> -- der er jo ikke nogen som tvinger dig til at skrive FileSystems som en
> impl. af Drives. Der er heller ikke nogen der tvinger dig dit ikke at
> gøre det.

Ah, point taken. Jeg kan jo ikke vide at de vil implementere det hele -
eller på samme måde - det er op til dem. I så fald må det ikke
være min opgave at fortælle hvordan implementationen bruges. Jeg kan
jo godt beskrive en måde jeg har forestilt mig det implementeret på -
men ellers er det helt op til brugeren af en implementation at finde ud
af hvordan den virker.
Men det jeg ellers havde i tanken: interoperabilitet. Hvis en
applikation er skrevet til at bruge xx.yy.drives.implementation.Drives
i deres applikation - og den implementation kun findes til Windows og
Linux, f.eks. Hvad så når de vil køre den på Mac? Så finder de en
implementation til Mac, men den er placeret i aa.bb.cc.Drives i stedet
- så skal de til at rette hele deres applikation igennem. Det var
egentlig det jeg var ude efter ikke skete.

> .. det bedste praktiske design kommer sjældent ved at jappe det sammen
> helt uden at tænke sig om ... men heller ikke ved at tænke alt igennem
> til perfektion (det ender tit med noget som ser smart ud, bare fordi det
> ikke er set før, men i virkeligheden er kluntet & forvirrende). Men hvis
> man tænker sig lidt om fra starten, gætter hvad der er væsentligst, og
> så retter til efterhånden (refactoring tools er godt) som de reelle
> betingelser og alle forglemmelserne viser sig, så kører det...

Point taken - igen Det kører det her.

> En abstrakt klasse kan forresten kun en ting ekstra: Erklære en
> ikkestatisk metode (eller _få_ den erklæret ved at implementere et
> interface hhv extende in abstrakt klasse), men undlade at implementere
> den. Og du kan altid lave en klasse abstrakt -- men må så ikke
> instantiere den.

Ja, det er korrekt. Men jeg har indset at jeg brugte min abstrakte
klasse helt forkert. Jeg lavede den abstrakt, fordi den så fungerede
som et interface, samtidig med at jeg kunne placerere en statisk metode
i den. Det har jeg droppet nu - i stedet laver jeg rene interfaces. Det
giver jo faktisk også mere overskuelighed.
Det kan dog være jeg laver nogle AbstractXX klasser som implementerer
nogle af de meget generelle metoder i interfacet XX - som en hjælp til
dem der laver en implementation.

Mvh.
Bjarke W.


Bjarke Walling Peter~ (22-01-2006)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 22-01-06 16:24

Thorbjørn Ravn Andersen wrote:
> Soren Kuula <dongfang@dongfang.dk> writes:
>
> > .. det bedste praktiske design kommer sjældent ved at jappe det sammen
> > helt uden at tænke sig om ... men heller ikke ved at tænke alt igennem
> > til perfektion (det ender tit med noget som ser smart ud, bare fordi
> > det ikke er set før, men i virkeligheden er kluntet &
> > forvirrende). Men hvis man tænker sig lidt om fra starten, gætter hvad
> > der er væsentligst, og så retter til efterhånden (refactoring tools er
> > godt) som de reelle betingelser og alle forglemmelserne viser sig, så
> > kører det...
>
> Det kan anbefales at lave den slags med unit tests da man så laver
> kode der skal bruge ens kode inden man skriver den faktiske kode. Man
> opdager mange uhensigtsmæssigheder på den måde.

Det lyder interessant. Hvordan fungerer det? Kan man teste på noget,
som ikke er skrevet endnu? Eller er pointen at testene fejler til at
starte med og så efterhånden, når man får skrevet mere og mere, så
skulle de sige 'ok'.

> Mht implements versus extends så er extends godt til dataklässer men
> ellers bruger jeg interfaces. Så er man mest fleksibel.

Klart nok.

Mvh.
Bjarke W.


Thorbjørn Ravn Ander~ (22-01-2006)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 22-01-06 16:41

"Bjarke Walling Petersen" <bjarke.walling@gmail.com> writes:

> Det lyder interessant. Hvordan fungerer det? Kan man teste på noget,
> som ikke er skrevet endnu? Eller er pointen at testene fejler til at
> starte med og så efterhånden, når man får skrevet mere og mere, så
> skulle de sige 'ok'.

Som jeg har forstået det og selv bruger det, så fungerer det sådan
nogenlunde sådan her, når man fx skal lave en ny metode, og har gjort
sig det nogenlunde klart hvad det er man vil.

FØRST skriver du en ny bid testkode som KALDER den kode du skal til at
skrive, og som kontrollerer at det resultat du får tilbage er rigtigt.

SÅ tilføjer du lige akkurat nok kode til at compileren kan oversætte
(Ctrl-1 er godt i Eclipse her), men som giver et forkert resultat (det
er vigtigt!).

SÅ testafvikler du og ser at din nytilføjne test fejler.

SÅ tilføjer du kun lige akkurat nok kode til at hele testafviklingen
lykkes igen. Her er det også vigtigt at holde det så enkelt som
muligt, da det er nemmest at rette til vha refaktorering senere når
koden skal kunne mere.

Denne cyklus gentages (især med fokus på randtilfælde) indtil man har
testkode der viser at alle interessante inddata til metoden giver det
forventede resultat.


Således tilføjer man løbende flere og flere tests til sin kode som
allesammen skal gå igennem hvis man afprøver dem (det er også
vigtigt). På et eller andet tidspunkt kan det være nødvendigt at
smide noget kode ud og lave det forfra - så har man en række tests som
SKAL gå igennem førend koden gør det samme som den kode den
erstattede.

Den sidste ting der er godt ved tests, er at det viser hvordan din
kode skal BRUGES. Det er faktisk kode som viser hvad der kommer ind
og hvad der forventes at komme ud - det er kernedokumentation.


Jeg har set ovenstående beskrevet grundigt, men kan ikke lgie hitte
det nu. jeg håber dog ovenstående giver en ide om hvad det drejer sig
om.

Du anbefales at kigge på jUnit pakken - der er glimrende dokumentaiton
til. Eclipse har integeret junit som gør det nemt at arbejde med.

Link: http://www.junit.org/index.htm

--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk/ravn/

Michael Rasmussen (22-01-2006)
Kommentar
Fra : Michael Rasmussen


Dato : 22-01-06 23:03

On Sun, 22 Jan 2006 16:40:46 +0100, Thorbjørn Ravn Andersen wrote:

>
> Jeg har set ovenstående beskrevet grundigt, men kan ikke lgie hitte det
> nu. jeg håber dog ovenstående giver en ide om hvad det drejer sig om.
Er det ikke eXtreme Programming, du tænker på - test driven development?

--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Thorbjørn Ravn Ander~ (22-01-2006)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 22-01-06 23:24

Michael Rasmussen <mir@miras.org> writes:

> Er det ikke eXtreme Programming, du tænker på - test driven development?

Jo - TDD men ikke XP - men jeg havde en specifik fremstilling i
tankerne, som sagde det meget klart og tydeligt, men som jeg
simpelthen ikke kan hitte igen lige nu.

Desværre er hovedparten af partsindlæggene ikke gode til at vise
hvorfor det er en fordel at arbejde sådan når man laver genbrugelig
kode, baseret på et konkret eksempel.

Ka'wær det dukker op igen en dag.
--
Thorbjørn Ravn Andersen


Michael Rasmussen (23-01-2006)
Kommentar
Fra : Michael Rasmussen


Dato : 23-01-06 00:03

On Sun, 22 Jan 2006 23:23:43 +0100, Thorbjørn Ravn Andersen wrote:

>
> Jo - TDD men ikke XP - men jeg havde en specifik fremstilling i tankerne,
> som sagde det meget klart og tydeligt, men som jeg simpelthen ikke kan
> hitte igen lige nu.
Er det argumentationen for TDD, du søger?
--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Michael Rasmussen (23-01-2006)
Kommentar
Fra : Michael Rasmussen


Dato : 23-01-06 00:16

On Sun, 22 Jan 2006 23:23:43 +0100, Thorbjørn Ravn Andersen wrote:

>
> Jo - TDD men ikke XP - men jeg havde en specifik fremstilling i tankerne,
> som sagde det meget klart og tydeligt, men som jeg simpelthen ikke kan
> hitte igen lige nu.
>
Dette essay? http://www.agiledata.org/essays/tdd.html
--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Thorbjørn Ravn Ander~ (30-01-2006)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 30-01-06 09:23

Michael Rasmussen <mir@miras.org> writes:

> > Jo - TDD men ikke XP - men jeg havde en specifik fremstilling i tankerne,
> > som sagde det meget klart og tydeligt, men som jeg simpelthen ikke kan
> > hitte igen lige nu.
> >
> Dette essay? http://www.agiledata.org/essays/tdd.html

Næh mere et konkret eksempel. Jeg faldt igen over eksemplet med
romertal, og det er faktisk en god artikel som når frem til noget kode
som man formentlig ikke ville have skrevet selv uden at have tænkt sig
rigtigt grundigt om.

http://www.differentpla.net/node/58

(Det er godt nok C++, men mon ikke det er til at gennemskue alligevel)
--
Thorbjørn Ravn Andersen


Michael Rasmussen (30-01-2006)
Kommentar
Fra : Michael Rasmussen


Dato : 30-01-06 09:43

On Mon, 30 Jan 2006 09:22:52 +0100, Thorbjørn Ravn Andersen wrote:

> http://www.differentpla.net/node/58
>
Den vil jeg studere nærmere.

> (Det er godt nok C++, men mon ikke det er til at gennemskue alligevel)
Hehe, C++ er mit hovedprogrammeringssprog, så det går nok lige
--
Hilsen/Regards
Michael Rasmussen
http://keyserver.veridis.com:11371/pks/lookup?op=get&search=0xE3E80917


Bjarke Walling Peter~ (22-01-2006)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 22-01-06 16:57

Thorbjørn Ravn Andersen wrote:
> "Bjarke Walling Petersen" <bjarke.walling@gmail.com> writes:
>
> > Det lyder interessant. Hvordan fungerer det? Kan man teste på noget,
> > som ikke er skrevet endnu? Eller er pointen at testene fejler til at
> > starte med og så efterhånden, når man får skrevet mere og mere, så
> > skulle de sige 'ok'.
>
> Som jeg har forstået det og selv bruger det, så fungerer det sådan
> nogenlunde sådan her, når man fx skal lave en ny metode, og har gjort
> sig det nogenlunde klart hvad det er man vil.
> [... længere beskrivelse ...]

Mange tak for det! Det vil jeg helt sikkert kigge på. Det lyder
virkelig smart. Og jeg bruger jo Eclipse, så det er da nemt, hvis det
er indbygget.

Mvh.
Bjarke W.


Thorbjørn Ravn Ander~ (22-01-2006)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 22-01-06 22:19

"Bjarke Walling Petersen" <bjarke.walling@gmail.com> writes:

> Mange tak for det! Det vil jeg helt sikkert kigge på. Det lyder
> virkelig smart. Og jeg bruger jo Eclipse, så det er da nemt, hvis det
> er indbygget.

Det er fikst, og giver en en helt anden måde at tænke på, samt en
meget høj sandsynlighed for at fx bibliotekskode bliver til at bruge.

Åhja, en ting til. Når der bliver fundet fejl i din kode, enten af
dig selv, eller af andre, behandler du dem lige sådan. Altså skriv en
test der viser problemet, og kontroller det ved at testen fejler.
Herefter retter du fejlen og ser at testen lykkes. Testen indgår
herefter naturligvis i porteføljen af ting der skal være i orden
således at man ikke ved et uheld introducerer fejlen igen.

Synes du den her indfaldsvinkel er interessant så søg lidt på "test
driven design" (fx testdriven.com).

Der er en artikel om hvordan man bruger junit i Eclipse på
http://www.onjava.com/pub/a/onjava/2004/02/04/juie.html


--
Thorbjørn Ravn Andersen


Bjarke Walling Peter~ (23-01-2006)
Kommentar
Fra : Bjarke Walling Peter~


Dato : 23-01-06 12:33

Michael Rasmussen skrev:
> Dette essay? http://www.agiledata.org/essays/tdd.html

Det ser jo ud til at vaere en rigtig god udviklingsmetode. Nu maa jeg
se med min fremtidige projekter, men jeg proever i hvert fald kraefter
med det paa det her projekt. Nu er det jo kort tid jeg har kendt til
det, men det virker som om at man rent faktisk udvikler det der er brug
for, - i stedet for hvad der kan vaere nemt - at taenke en masse paa de
features man gerne vil have.

Mvh.
Bjarke W.


Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407944
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste