Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Det finns en del oklarheter i instruktionerna. Ordet "backend" antyder för mig en separat tjänst som kör på en annan maskin, eller åtminstone i en annan process om det är på samma maskin.

Det som beskrivs är dock Java-klasser och -gränssnitt. Det antyder för mig att uppgiften är att skriva affärslogiken (a.k.a "modellen" - M:et i MVC), inte en fullskalig backend med HTTP-gränssnitt. Frontend-teamet antas implementera V- och C-delarna.

Det står i beskrivningen att "ett annat frontend team är försenade och ska koppla in sitt gränssnitt mot backendet du bygger," vilket jag tolkar som att gränssnittet fortfarande kan omförhandlas. Mitt förslag blir då som följer:

Min design

En bok har inget beteende i detta sammanhanget. Vi ska inte t.ex. läsa böcker. Därför är det rimligt att implementera Book som en enkel data-struktur (‘immutable’, med publika fält):

publicfinalclassBookID {
publicfinalStringisbn;
publicBookID(Stringisbn) {
// ...
}
}
publicfinalclassBook {
publicfinalBookIDid;
publicfinalStringtitle;
publicfinalStringauthor;
publicfinalBigDecimalprice;
publicBook(BookIDid, Stringtitle, Stringauthor, BigDecimalprice) {
// ...
}
}

Det står inget i beskrivningen om hur varukorgen ska sparas. Låt oss tills vidare anta att den inte behöver sparas och att man helt enkelt skapar den i frontend. En representation ska dock skickas till "backend." Förmodligen räcker det med en java.util.Collection<OrderLineItem>:

publicfinalclassOrderLineItem {
publicfinalBookIDbookID;
publicfinalintquantity;
}
publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
// ...
}

I uppgiftsbeskrivningen står det att buy() ska returnera en int[] med värdena OK, NOT_IN_STOCK och DOES_NOT_EXIST. Det är ett vanligt sätt att returnera en status i C-kod, men Java har exceptions som är mycket bättre att använda för att rapportera fel. För att ta reda på status för en specifik bok kan vi lägga till ett API specifikt för det:

publicclassBookStore {
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
// ...
}

Man ska också kunna söka efter böcker. Min erfarenhet är att Java-arrayer tenderar att skapa komplex kod. Därför ändrar jag retur-värdet för list()-metoden:

publicclassBookStore {
java.util.Set<Book> list(StringsearchString);
// ...
}

Hela BookStore-gränssnittet blir som följer:

publicclassBookStore {
voidbuy(java.util.Collection<LineItem> books)
throwsNoSuchBookException, NotInStockException;
intgetStockQuantity(BookIDbookID)
throwsNoSuchBookException;
java.util.Set<Book> list(StringsearchString);
}

För att köpa, måste man veta totalpris inklusive frakt mm. och göra enbetalning. Hur detta gör till beskrivs inte i uppgiften, så jag antar att det ska läggas till senare. Eftersom jag inte har de detaljerna väljer jag i sann "agile"-anda att ignorera dem.

Notera att om det inte beskrevs ett separat frontend-team hade jag undvikit en så här noggrann upfront-design. Enligt TDD ska designen göras inkrementellt och förändras med tiden allteftersom man lär sig av att utföra implementationen. Har man ett separat team antar jag att det tar tid att kommunicera med dem och att man därför behöver bestämma en ganska detaljerad design innan arbetet påbörjas.


Sök-funktionen är inte väl testad. Algoritmen är implementerad i testet, inte i BookStore. Jag känner att det kan bli svårt att hitta en algoritm som implementeras av BookStore utan att generera SQL-frågor, och SQL-frågor kan inte testas utan en databas. Se det skulle inte längre vara enhetstest.


Konsoll-appen har inga enhetstest. Den kan bara köras manuellt. Så det är så jag har testat den. Anledningen är att den bara skulle vara en stand-in för frontend-teamets arbete.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages