项目作者: RickardPedersen

项目描述 :
Assignment in Object-oriented analysis and design at Nackademin
高级语言: JavaScript
项目地址: git://github.com/RickardPedersen/OOAD-assignment-1.git
创建时间: 2020-10-10T19:46:08Z
项目社区:https://github.com/RickardPedersen/OOAD-assignment-1

开源协议:

下载


OOAD-assignment-1

Assignment in Object-oriented analysis and design at Nackademin

GitHub: https://github.com/RickardPedersen/OOAD-assignment-1

Setup

Install dependencies

  1. npm install

Start app with live server

  1. npm start

Uppgift

Välj 3 valfria designmönster från boken ”Learning JavaScript Design Patterns”

  1. Facade Pattern
  2. Factory Pattern
  3. Revealing Module Pattern

Beskrivning av mina designmönster

Facade Pattern

Facade Pattern är ett strukturellt designmönster vilket innebär att det behandlar relationer mellan objekt.

Grundprincipen bakom Facade Pattern är att dölja komplex kod eller stora kodblock bakom ett användarvänligt gränssnitt.

jQuery är ett exempel på Facade Pattern. Med jQuery kan utvecklare på ett enkelt sätt hantera bland annat DOM-manipulation och AJAX-requests, som innan ES6 var väldigt komplext med JavaScript.

Exempel

Så här kan det se ut om man inte använder Facade Pattern:

  1. async function withoutFacade() {
  2. async function getUsers() {
  3. const response = await fetch('https://jsonplaceholder.typicode.com/users', {
  4. method: 'GET',
  5. headers: { 'Content-Type': 'application/json' }
  6. })
  7. return response.json()
  8. }
  9. async function getUserPosts(userId) {
  10. const response = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${userId}`, {
  11. method: 'GET',
  12. headers: { 'Content-Type': 'application/json' }
  13. })
  14. return response.json()
  15. }
  16. const users = await getUsers()
  17. console.log(users)
  18. for (const user of users) {
  19. const posts = await getUserPosts(user.id)
  20. console.log(posts)
  21. }
  22. }
  23. withoutFacade()

Vi kan istället dölja den komplexa koden bakom en fasad som skulle kunna se ut så här.
I detta exemplet är fasaden inbygd i en Revealing Module. Du kan läsa mer om Revealing Module Pattern längre ner.

  1. const rixios = (function () {
  2. const privateDefaultHeaders = { 'Content-Type': 'application/json' }
  3. async function publicGet(url = '', config = {}) {
  4. if (this.baseUrl) {
  5. url = this.baseUrl + url
  6. }
  7. const { headers, params } = config
  8. return await privateRequest(url, {
  9. method: 'GET',
  10. headers: headers || privateDefaultHeaders,
  11. params: { ...params },
  12. })
  13. }
  14. async function privateRequest(url, options) {
  15. const queryString = Object.entries(options.params)
  16. .map((param) => {
  17. return `${param[0]}=${param[1]}`
  18. })
  19. .join('&')
  20. const fullUrl = `${url}?${queryString}`
  21. delete options.params
  22. console.log(`${options.method} ${fullUrl}`)
  23. const res = await fetch(fullUrl, options)
  24. return res.json()
  25. }
  26. function publicCreate(baseUrl) {
  27. return {
  28. baseUrl,
  29. get: publicGet,
  30. }
  31. }
  32. return {
  33. get: publicGet,
  34. create: publicCreate,
  35. }
  36. })()

Nu har utvecklarna tillgång till ett användarvänligt gränssnitt!
Så här skulle det kunna se ut:

  1. async function withFacade() {
  2. const jsonplaceholder = rixios.create('https://jsonplaceholder.typicode.com')
  3. async function getUsers() {
  4. return await jsonplaceholder.get('/users')
  5. }
  6. async function getUserPosts(userId) {
  7. return await jsonplaceholder.get('/posts', { params: { userId } })
  8. }
  9. const users = await getUsers()
  10. console.log(users)
  11. for (const user of users) {
  12. const posts = await getUserPosts(user.id)
  13. console.log(posts)
  14. }
  15. }
  16. withFacade()

Factory Pattern

Factory Pattern är, till skillnad från Facade Pattern, ett Skapande designmönster, vilket innebär att det behandlar mekanismer för objektskapande.
Istället för att skapa object med nyckelordet new så låter vi vår Factory skapa objektet åt oss.

Exempel

Vi börjar med att definera våra classer:

  1. class Vehicle {
  2. constructor({ name, id }) {
  3. this.name = name
  4. this.id = id
  5. }
  6. }
  7. class Rocket extends Vehicle {
  8. constructor({ name, id, description, active }) {
  9. super({ name, id })
  10. this.description = description
  11. this.active = active
  12. }
  13. }
  14. class Dragon extends Vehicle {
  15. constructor({ name, id, description, active }) {
  16. super({ name, id })
  17. this.description = description
  18. this.active = active
  19. }
  20. }
  21. class Ship extends Vehicle {
  22. constructor({ name, id, type, roles }) {
  23. super({ name, id })
  24. this.type = type
  25. this.roles = roles
  26. }
  27. }

Så här skapar man objekt enligt Constructor Pattern:

  1. const rocket = new Rocket()
  2. const dragon = new Dragon()
  3. const ship = new Ship()

Men vi kan istället bygga en fabrik som skapar object åt oss:

  1. class VehicleFactory {
  2. constructor() {
  3. this.vehicleClass = Vehicle;
  4. }
  5. createVehicle(options = {}) {
  6. switch (options.vehicleType) {
  7. case 'rocket':
  8. this.vehicleClass = Rocket
  9. break
  10. case 'dragon':
  11. this.vehicleClass = Dragon
  12. break
  13. case 'ship':
  14. this.vehicleClass = Ship
  15. break
  16. default:
  17. this.vehicleClass = Vehicle
  18. break
  19. }
  20. return new this.vehicleClass(options)
  21. }
  22. }

Nu kan vi på ett enkelt sätt skapa många olika typer av object genom att använda vår fabrik.

  1. const factory = new VehicleFactory()
  2. const rocket = factory.createVehicle({ vehicleType: 'rocket' })
  3. const dragon = factory.createVehicle({ vehicleType: 'dragon' })
  4. const ship = factory.createVehicle({ vehicleType: 'ship' })

Revealing Module Pattern

Revealing Module Pattern är, precis som Facade Pattern, ett strukturellt designmönster, som behandlar relationer mellan objekt.
Till skillnad från Facade Pattern, så används Revealing Module Pattern för att efterlikna klasser med public och private inkapsling, en funtionalitet som ES6 klasser har begränsat stöd för. På så sätt kan vi skydda variabler och metoder från det globala scopet.
Revealing Module Pattern är en “förbättrad” version av Module Pattern som är väldigt liknande.

Exempel

I Module Pattern så defineras alla privata variabler och metoder i det privata scopet och alla publika i det publika return-objektet.

  1. const modulePattern = (function () {
  2. // Encapsulation
  3. let counter = 0 // private variable
  4. return {
  5. // public methods
  6. incrementCounter: function () {
  7. return counter++
  8. },
  9. resetCounter: function () {
  10. console.log("counter value prior to reset: " + counter)
  11. counter = 0
  12. }
  13. }
  14. })()

Med Revealing Module Pattern så definerar vi istället alla varibler och metoder i det privata scopet och sen avslöjar (revealar) vi de variabler och metoder som ska vara publika.

  1. const revealingModulePattern = (function () {
  2. let privateCounter = 0
  3. function publicIncrementCounter () {
  4. return privateCounter++
  5. }
  6. function publicResetCounter () {
  7. console.log("counter value prior to reset: " + privateCounter)
  8. privateCounter = 0
  9. }
  10. // Reveal public pointers to
  11. // private functions and properties
  12. return {
  13. incrementCounter: publicIncrementCounter,
  14. resetCounter: publicResetCounter
  15. }
  16. })()

Dokumentation

Min kund är SpaceX som vill att jag bygger en webbsida åt dom.

Den strategiska nivån

Intervju med Elon Musk:

Vi vill visa upp våra raketer, kapslar (dragons) och båtar.
Vi vill få så många besökare som möjligt (globalt).
Webbsidan ska ha ett rymdtema.
Webbsidan ska väcka intresse för rymden och SpaceX hos besökaren.
Webbsidan ska vara cool.

Produktmål

  • Visa racketer, dragons och båtar.
  • Locka så många besökare som möjligt.
  • Coolt och inspirerande rymdtema.

Intervju med potentiella användare:

Jag vill få en beskrivning av dom olika rymdfordonen.
Jag vill se vad båtarna används till.
Jag vill kunna använda webbsidan på min dator och telefon.
Jag vill se många bilder.

Användarbehov

  • Se information om de olika rymdfordonen.
  • Se vad båtarna används till.
  • Se bilder på rymden och fordonen.
  • Kunna använda webbsidan på dator och mobila enheter.

Omfattningsnivån

Kravspecifikation

Innehåll:

  • Alla fordon visas med namn, bild.
  • Raketer och Dragons visas med beskrivning.
  • Båtar visas med information om användingsområden.
  • Rymdbilder.

Funktionalitet:

  • Hämta data från SpaceX API

UML-diagram

Klassdiagram

class diagram

Användningsfallsdiagram

Use case diagram

Aktivitetsdiagram

Activity diagram