Indledende Programmering Uge 6 - Efterår 2006 Design af klasser Susanne Lindros
Plan for i dag Design af Klasser / programkvalitet Refaktorering Dubleret kode Kvalitetsegenskaberne kobling og binding Bedre kobling gennem indkapsling Bedre kobling og binding gennem ansvarsfordeling Refaktorering Optællingstyper (enum) Klasse metoder herunder main() Gennemgående eksempel World of Zulu
Design af klasser / programkvalitet Programmer af god kvalitet er bl.a. Lette at vedligeholde Lette at udvide Lette at teste Dvs. programmerne er: Løst koblede (loose coupling) Stærkt bundne/stærkt sammenhængende (high cohesion)
Klassediagram for World of Zuul
Dubleret kode Når den samme kodeblok forekommer flere steder i et program, kaldes det dubleret eller redundant kode Dubleret kode er tegn på dårligt design, og skal undgås (Hvorfor det?)
Kobling Begrebet kobling beskriver samspillet mellem klasser Vi tilstræber løs kobling (loose coupling) Dvs. klasserne skal være så uafhængige af hinanden som muligt og kun kommunikere med hinanden via en lille veldefineret grænseflade Stærk kobling = høj afhængighed og medfører at der skal rettes mange steder når der sker ændringer
Binding Begrebet binding beskriver i hvilken grad programmets moduler (klasser og metoder) løser én og kun én klart defineret opgave Vi tilstræber stærk binding (high cohesion) Dvs. hvert modul har en klart defineret opgave og et klart defineret ansvarsområde Det medfører at modulerne er Lette at læse Lette at rette Lette at genbruge
Indkapsling Indkapsling er med til at skabe løs kobling Kun klassens Interface skal være synligt udefra, dvs. hvilke metoder klassen tilbyder og hvordan de anvendes Felter bør altid erklæres private Al tilgang til klassens data er klassens eget ansvar og bør kun ske i klassens egne metoder
Fordeling af ansvar (Responsibility-driven design) Hver klasse skal have et klart defineret ansvarsområde skal kun være ansvarlig for én type entiteter Hver klasse skal være ansvarlig for at lagre og manipulere sine egne data Klassen må gerne bede andre om hjælp, men bevarer selv ansvaret for hvad der sker Medfører løs kobling og stærk binding
Refaktorering Refaktorering er en aktivitet hvor man forbedrer strukturen og koden i et program med henblik på at gøre det lettere at ændre og tilføje ny funktionalitet Refaktorering ændrer ikke ved den aktuelle funktionalitet (kvalitetsforbedrer kun koden) Refaktorering medfører ofte at klasser og metoder deles op
Refaktorering og Test Et sikkert refaktorerings forløb: Gennemfør test der viser at koden virker Tag kopi af koden Refaktorer (lav kvalitetsforbedring) Test igen og kontroller at alt stadig virker Nu er vi parate til at tilføje ny funktionalitet
Optællingstyper (enum) En Java feature med mange muligheder, her kun en introduktion enum definerer en type på samme måde som en klasse Simpel anvendelse - en liste af navne public enum CommandWord { GO, QUIT, HELP, UNKNOWN; } Hvert navn repræsenterer et objekt af optællingstypen (oprettet implicit) F.eks. CommandWord.HELP
Optællingstyper (enum) public enum CommandWord { GO, QUIT, HELP, UNKNOWN; } private String command; private CommandWord commandWord; … if (command.equals(“help”)) commandWord = CommandWord.HELP; if (commandWord == CommandWord.HELP) printHelp();
Klasse Metoder Klasse metoder defineres som static Klasse metoder kan kaldes direkte på klassen, f.eks.: Math.round(3.75); Klasse metoder kan kun tilgå andre klasse elementer (variable og metoder) Klasse metoder kan aldrig direkte tilgå instans variable og ikke-klasse metoder
Afvikling af programmer uden for BlueJ Hvis java-applikationer skal kunne afvikles uden for BlueJ skal de have en main() metode public static void main (String [] args) { … } main() metoden udføres automatisk når vi eksekverer en klasse Alle klasser kan have en main() metode, men ofte findes den kun i applikationens ”start” klasse
”Start” klasse til World of Zuul public class WorldOfZuul { public static void main(String[] args) { Game myGame = new Game(); myGame.play(); }
main() metode i Game klassen public class Game { ... public static void main(String[] args) { Game myGame = new Game(); myGame.play(); }