Skip to content
Snippets Groups Projects
Commit 470b7a9f authored by dagk's avatar dagk
Browse files

Foiler for mandag, kode for mandag + onsdag uke 10

parent cbe3cce0
No related branches found
No related tags found
No related merge requests found
Showing
with 515 additions and 0 deletions
File added
File added
package uke10.delegering;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
interface Observer {
void update(String event);
}
class EventSource {
List<Observer> observers = new ArrayList<>();
void notifyObservers(String event) {
observers.forEach(observer -> observer.update(event));
}
void addObserver(Observer observer) {
observers.add(observer);
}
void scanSystemIn() {
var scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
notifyObservers(line);
}
scanner.close();
}
}
public class ObserverScanner {
public static void main(String[] args) {
System.out.println("Skriv inn tekst : ");
var eventSource = new EventSource();
eventSource.addObserver(event -> {
System.out.println("Tok imot streng: " + event);
});
eventSource.addObserver(event -> {
System.out.println("Antall bokstaver: " + event.length());
});
eventSource.addObserver(event -> {
System.out.println("Ordene: " + String.join(", ", event.split(" ")));
});
eventSource.scanSystemIn();
}
}
\ No newline at end of file
package uke10.delegering.boss;
public class Boss extends Worker {
Worker secretary;
@Override
public String work() {
if (this.secretary != null) {
return secretary.work();
}
return "Boss doin' work";
}
public void setSecretary(Worker secretary) {
this.secretary = secretary;
}
public static void main(String[] args) {
Boss boss = new Boss();
System.out.println(boss.work());
boss.setSecretary(new Secretary());
System.out.println(boss.work());
}
}
package uke10.delegering.boss;
public class Secretary extends Worker {
@Override
public String work() {
return "Dette er arbeidet til sekretæren.";
// Hva vil super være en referanse til, og hva skjer om vi kaller super.work()?
}
}
package uke10.delegering.boss;
public class Worker {
public String work() {
return "standard jobb til en Worker";
}
}
package uke10.delegering.boss.uteninterface;
public class Boss extends Worker {
Worker secretary;
@Override
public String work() {
if (this.secretary != null) {
return secretary.work();
}
return "Boss doin' work";
}
public void setSecretary(Worker secretary) {
this.secretary = secretary;
}
public static void main(String[] args) {
Boss boss = new Boss();
System.out.println(boss.work());
boss.setSecretary(new Secretary());
System.out.println(boss.work());
}
}
package uke10.delegering.boss.uteninterface;
public class Secretary extends Worker {
@Override
public String work() {
return "Dette er arbeidet til sekretæren.";
// Hva vil super være en referanse til, og hva skjer om vi kaller super.work()?
}
}
package uke10.delegering.boss.uteninterface;
public class Worker {
public String work() {
return "standard jobb til en Worker";
}
}
package uke10.delegering.kokk;
/*
* Grensesnittet som enhver kokk må oppfylle.
* Hovedkokken ChefdelaChef og underkokkene fyller alle denne rollen.
*/
public interface Chef {
public String makeMain();
public String makePotatoes();
public String makeSauce();
}
package uke10.delegering.kokk;
import java.util.Random;
/*
* Hovedkokken har ansatt to kokker til å gjøre arbeidet sitt. Det
* er jo det delegering handler om! I tillegg er det tilfeldig hvilken
* av de to kokkene som faktisk lager maten. Legg merke til at this.makeSauce()
* dermed knyttes direkte videre til underkokk.makeSauce(). Husk også at en kan
* gjøre litt mer, en trenger ikke ha en helt dum metode for å kalle det
* delegering. ChefdelaChef gjør noe - hen velger hvilken kokk som skal lage
* maten.
*/
public class ChefdelaChef implements Chef{
Chef kokk1 = new Kokk1();
Chef kokk2 = new Kokk2();
final Random random = new Random();
public static void main(String[] args) {
ChefdelaChef dude = new ChefdelaChef();
System.out.println(dude.todaysMenu());
}
public String todaysMenu() {
String menu = "Dagens rett er ";
menu += this.makeMain();
menu += " med ";
menu += this.makePotatoes();
menu += " og ";
menu += this.makeSauce();
menu += ".";
return menu;
}
/*
* ChefDelaChef har to kokker. Og velger tilfeldig hvilken av de to som
* faktisk lager maten. Det kan gi opphav til spesielle kombinasjoner...
*/
@Override
public String makeMain() {
return random.nextBoolean()? kokk1.makeMain():kokk2.makeMain();
}
@Override
public String makeSauce() {
return random.nextBoolean()? kokk1.makeSauce():kokk2.makeSauce();
}
@Override
public String makePotatoes() {
return random.nextBoolean()? kokk1.makePotatoes():kokk2.makePotatoes();
}
}
package uke10.delegering.kokk;
public class Kokk1 implements Chef {
@Override
public String makeSauce() {
return "honning";
}
@Override
public String makeMain() {
return "pannekaker";
}
@Override
public String makePotatoes() {
return "pommes frites";
}
}
package uke10.delegering.kokk;
public class Kokk2 implements Chef {
// Kanskje kokk2 kan sette bort arbeidet til enda en kokk, skjult for sjefen?
// Dobbeldelegering!
Chef kokk3 = new Kokk3();
// Denne kokken setter bare bort mekking av saus til kokk3.
@Override
public String makeSauce() {
return kokk3.makeSauce();
}
@Override
public String makeMain() {
return "entrecôte";
}
@Override
public String makePotatoes() {
return "hasselbackpoteter";
}
}
package uke10.delegering.kokk;
public class Kokk3 implements Chef {
// Kanskje kokk2 kan sette bort arbeidet til enda en kokk, skjult for sjefen?
@Override
public String makeSauce() {
return "ketchup";
}
@Override
public String makeMain() {
return "ostesmørbrød";
}
@Override
public String makePotatoes() {
return "kokte poteter";
}
}
package uke10.delegering.person;
import java.util.ArrayList;
import java.util.List;
public class Person {
// Oversikten over barn er delegert til et liste-objekt.
// Referansen er komposisjon
// så dersom Person-objektet slettes så vil også barna slettes.
// Hvis det finnes referanser til children-objektet andre steder, så vil
// ikke listen slettes. (Det måtte være kode i Person-klassen pga innkapslingenen)
// Det ville jo være dog være uvanlig/unaturlig.
List<Person> children = new ArrayList<>();
@Override
public String toString() {
return String.format("%s (%d)",name, age);
}
String name;
int age;
int getChildCount() { return children.size();}
Person getChild(int i) {return children.get(i);}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void addChild(Person child) {
children.add(child);
}
public static void main(String[] args) {
Person p = new Person("Børge", 46);
Person j = new Person("Jørn", 13);
Person h = new Person("Håvard", 11);
p.addChild(j);
p.addChild(h);
System.out.println(p.getChildCount());
System.out.println(p.getChild(1));
}
}
package uke10.delegering.settings;
import java.util.HashMap;
import java.util.Map;
public class DefaultingSettings implements ISettings {
Map<String, Object> getSettings();
private MapSettings userSettings = new MapSettings(); // kunne vært deklarert som ISettings.
private ISettings defaultSettings;
public DefaultingSettings(ISettings defaultSettings) {
this.defaultSettings = defaultSettings;
}
@Override
public boolean hasSetting(final String s) {
return userSettings.hasSetting(s) || defaultSettings.hasSetting(s);
}
@Override
public Object getSetting(final String s) {
if (userSettings.hasSetting(s)) {
return userSettings.getSetting(s);
}
if (defaultSettings != null) {
return defaultSettings.getSetting(s);
}
return null;
}
@Override
public void updateSetting(final String s, final Object o) {
userSettings.updateSetting(s, o);
}
public void addSettingsIfAbsent(Map<String, Object> result) {
userSettings.addSettingsIfAbsent(result);
defaultSettings.addSettingsIfAbsent(result);
}
private Map<String, Object> effectiveSettings() {
Map<String, Object> result = new HashMap<>();
addSettingsIfAbsent(result);
return result;
}
public static void main(final String[] args) {
// Se klasse og objekt-diagrammer i egne filer
ISettings defaultGeneral = new MapSettings();
ISettings generalSettings = new DefaultingSettings(defaultGeneral);
ISettings settings = new DefaultingSettings(generalSettings);
// Setting default general settings
defaultGeneral.updateSetting("theme", "light");
defaultGeneral.updateSetting("font", "times new roman");
defaultGeneral.updateSetting("fullscreen", "yes");
System.out.println("\nSettings after default general settings have been set");
System.out.println("Font: "+settings.getSetting("font"));
System.out.println("Theme: "+settings.getSetting("theme"));
System.out.println("Fullscreen: "+settings.getSetting("fullscreen"));
// Setting general user settings that override general default settings
generalSettings.updateSetting("theme", "dark");
generalSettings.updateSetting("font", "courier new");
System.out.println("\nAfter setting user general settings");
settings.updateSetting("font", "comic sans");
System.out.println("Font: "+settings.getSetting("font"));
System.out.println("Theme: "+settings.getSetting("theme"));
System.out.println("Fullscreen: "+settings.getSetting("fullscreen"));
settings.updateSetting("theme", "dark");
System.out.println("\nAfter setting user project Settings");
System.out.println("Font: "+settings.getSetting("font"));
System.out.println("Theme: "+settings.getSetting("theme"));
System.out.println("Fullscreen: "+settings.getSetting("fullscreen"));
System.out.println(((DefaultingSettings)settings).effectiveSettings());
}
}
package uke10.delegering.settings;
import java.util.Map;
public interface ISettings {
boolean hasSetting(String s);
Object getSetting(String s);
void updateSetting(String s, Object o);
void addSettingsIfAbsent(Map<String, Object> result);
}
package uke10.delegering.settings;
import java.util.HashMap;
import java.util.Map;
public class MapSettings implements ISettings {
private final Map<String, Object> settings = new HashMap<>();
@Override
public boolean hasSetting(final String s) {
return settings.containsKey(s);
}
@Override
public Object getSetting(final String s) {
return settings.get(s);
}
@Override
public void updateSetting(final String s, final Object o) {
settings.put(s, o);
}
public void addSettingsIfAbsent(Map<String, Object> result) {
settings.forEach(result::putIfAbsent);
}
public void printSettings() {
System.out.println(settings);
}
public static void main(final String[] args) {
ISettings settings = new MapSettings();
settings.updateSetting("font", "Courier");
settings.updateSetting("errorColor", "Red");
System.out.println(settings.getSetting("font"));
System.out.println(settings.getSetting("errorColor"));
}
}
# Delegering brukt i et settings-hiarki
Instillinger er her et sett med nøkkelord og tilhørende verdier (key-value pairs), som håndteres godt av Map-interfacet i Java (tilsvarende Dictionary i Python).
I en applikasjon, så vil det typisk være standard-instillinger (default settings), som
en bruker kan endre.
Innstillingene (både default og de bruker-definerte) kan videre være **lagdelt**. I VSCode f.eks. så vil en ha instillinger som gjelder brukeren generelt, og instillinger som gjelder et konkret prosjekt. (En kan også skifte mellom flere sett med instillinger på hvert nivå, men det tar vi ikke høyde for i dette eksempelet).
I koden har vi et interface ISettings som definerer et felles grensesnitt for de to klassene
MapSettings og DafaultingSettings.
MapSettings-klassen svarer til bruker-settings: Den delegerer til et Map-objekt for å finne instllinger.
DefaultingSettings-klassen svarer til ett lag i beskrivelsen over, f.eks. prosjekt-settings. Den har to sett med settings-objekter. Et som typisk håndterer bruker-instillinger, og et som håndterer **verdier som ikke er satt av bruker på dette nivået**.
Hvis det ikke er flere nivåer, så vil det kun være default-verdier, som da er et MapSettings-objekt. Hvis det er flere nivåer, så er det et nytt DefaultingSettings-objekt, f.eks. **brukerinstillinger**. De som brukeren har satt, ligger da dettes objektets userSettings-objekt, mens default i defaultSettings.
Hvis det er flere nivåer, så forsetter dette rekursivt, med ny DefaultingSettings-objekt etc.
@startuml
interface ISettings {
+ boolean hasSetting(String s);
+ Object getSetting(String s);
+ void updateSetting(String s, Object o);
}
class MapSettings implements ISettings
class DefaultingSettings implements ISettings
DefaultingSettings *-- MapSettings
DefaultingSettings o-- DefaultingSettings
MapSettings *-- Map
@enduml
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment