#let glob_color = luma(110)
#set text(font: "Arial", glob_color)
#set text(font: "Virgil 3 YOFF", size: 10pt, glob_color)
#set page(margin: (x: 16pt, y: 16pt))
#show math.equation: it => {text(font: "Virgil 3 YOFF", size: 7pt)[#it]}
#show text.where(style: "italic"): it => text(size: 8pt, red, it)

#show heading: it => text(luma(0), it)
#show emph: it => text(luma(0), it)
#set list(marker: none)

#let note(heading, body) = {
  text(size: 12pt, heading, luma(0))
  body
}
#columns(2, gutter: 4pt)[
  == Requirments og ehv

  #note(
    "Epic:",
    [ a high-level grouping of features that represent a business goal.]
  ) 

  #note(
    "Feature:",
    [ a capability of the project that fulfills one or more stakholder needs. Described in a short and concise way, fx. 'auto-filled suggestions when typing'. Features are the middle ground between #emph[needs] and #emph[requirements]]
  )

  #note("Need:", [ a high-level goal that the stakeholder wants to achieve and the system should support, fx. "The search engine needs to deliver fast and accurate data so that they will choose to use it again".])

  #note(
    "Requirement:",
    [ the form a feature need to take to fulfill it's need. fx. "as a user i want to be able to order the results i get by date"]
  )

  #note(
    "User story:",
    [ as a #emph[role], I want #emph[feature] that #emph[reason] ]
  )

  == Estimations og læti

  #note(
    "Acceptance criteria:",
    [ a set of conditions that need to be met for a feature to be considered complete. fx "The results can be ordered in both ascending and descending order of date" ]
  )

  #note(
    "T-shirt sizing:",
    [ estimation of net business value against the effort required. Used in the #emph[initial] stages of a project to decide on the general project scope]
  )

  #note(
    "Projection from counts:",
    [ use the number of features multiplied by the avarage time it took to complete them to estimate the time required to complete rest of the features. Use this method when you have a lot of similar features.]
  )

  #note(
    "PERT (three point estimate):",
    [ use early in a project to get an estimate from an expert in the subject, ((BC + 4) \* ML + WC / 6) ]
  )

  = Android UI

  #note(
    "Layout:",
    [ defines a set of UI #emph([widgets]) and their positions on screen. #emph([Widgets]) can include text, images, interactive elements or even other widgets. Together #emph([widgets]) form a #emph([view hierarchy]) via nesting (like in html). ]
  )

  #note(
    "Activity:",
    [ controls user interaction with the UI, they can be thought of as controllers for the app. When an #emph([activity]) is instantiated its #emph([onCreate]) method is called. This is where the UI is inflated from an XML layout file. The #emph([setContentView()]) method is used to set the #emph([layout]) for the #emph([activity]).]
  )

  #note(
    "Fragments: ",
    [ controllers for independent sections of an #emph([activity]). They can be used to create multi-pane UIs for tablets or to reuse UI components across multiple #emph([activities]). ]
  )

  == Activity lifecycle og minni?

  #note(
    "Activity state",
    [ can be saved via the #emph([onSaveInstanceState(Bundle)]) to an activity record and then restored in the #emph([onCreate(Bundle)]) method from the same activity record ]
  )

  #emph([savedInstanceState]) is a #emph([Bundle]) object that can be used to store data when an #emph([activity]) is destroyed and recreated. This is useful for storing data that should persist across #emph([activity]) instances, can only be access by the activiy that created it. However it can be destroyed to free memory at any time.

  == Persistant alternatives
  - #emph([Static media]), located in the #emph([resource]) folder, images, strings and such, cannot be modified
  - An environment file (#emph([sharedPreferences])), key value map of simple app specific values, can be modified
  - #emph([Cached data]), files in the app's private internal storage directory, can be modified
  - #emph([Dynamic unnstructured data]), files in other folders such as the #emph([external storage]) directory, can be modified
  - #emph([Dynamic structured data]), stored in a local SQLite database, can be modified
  - #emph([Remote data]), data stored on a server, can be modified
  - #emph([Room]), split into #emph([Entities]) (single columns), #emph([DAOs]) (data access objects) and #emph([Databases]) (collection of entities and DAOs), can be modified


  == Agile
  The manifesto for agile software development is based on 4 main values:
  - #emph([Individuals]) and #emph([interactions]) over _processes and tools_
  - #emph([Working software]) over _comprehensive documentation_
  - #emph([Customer collaboration]) over _contract negotiation_
  - #emph([Responding to change]) over _following a plan_

  == Technical debt quadrant
  #image("technical_debt_quadrant.png")
  #list(
    marker: none,
    [#emph[del/reck: ] debt incurred because of underestimation ],
    [#emph[del/prud: ] debt incurred after informed cost analysis ],
    [#emph[ind/reck: ] debt incurred because of a lack of knowledge],
    [#emph[ind/prud: ] debt incurred despite trying to avoid because new info surfaces into project]
  )
]

== Background work

#note(
  "Persistent work",
  [ should use a #emph[WorkManager] ie. be scheduled, the definition of #emph[persistent] work is that it should stay scheduled even if the app is closed. If the work needs to be run immiediately it should be run on a specific #emph[Expidited] schedule for the #emph([WorkManager]). Since the work can be run even if the app is restarted we can add constrains to when it is run for example only when the battery is above a certain level.

  An example of this would be tracking GPS location in the background, the work should be run even if the app is closed and should be run at a specific time.

  #emph[Impersistent work] is more used than persistant work, it is work that does not persist between app restarts and can be run again anytime. Since this is more often than not network related work it should be run on a #emph[corutine] or a #emph[thread].

  An example of an #emph[immediate impersistent] work would be sending the user a notification when a message comes in, once the notification is sent the work is done and does not need to be run again. ]
)

#note(
  "Long running tasks",
  [ like downloads should be run on their own thread.]
)

#note(
  "Deferrable tasks",
  [ tasks that can be run later, can be scheduled to run at a later time or when certain conditions are met, for example alarms. An #emph[impersistent deferrable] task would be updating fetching if there is new data from a server but waiting on updating said data untill the user interacts with the app ]
)

== Patterns

#note(
  "Iterator pattern",
  [ is used to traverse a container and access its elements without exposing its underlying representation. We use it to traverse different types of collections in a uniform way. We can create an #emph[iterator] that iterates over either an array or a linked list without changing the code that uses the iterator. ]
)

#note(
  "Composite pattern",
  [ used to treat both singular and collections of objects uniformly. It is used to create a tree structure of objects. We can create a #emph[composite] object that can contain either a single object or a collection of objects. This allows us to treat both types of objects uniformly. ]
)

#note(
  "Decorator pattern",
  [ is used to add functionality to an object without changing its structure. We can create a #emph[decorator] object that adds additional functionality to an existing object. This allows us to add new functionality to an object without changing the object itself. ]
)