---
# System prepended metadata

title: Presentatie voorbereiding

---


# Iteration 3 aanpak
- multiple displays
- resize events
    - event catchen en deelop() oproepen?
- directory views and opening files
- JSON-as-file-system







# Presentatie voorbereiding
- Verdeling:
    - Edouard: GRASP over Files, File, Cursor, Buffer + tests
    - Victor: GRASP over alles van tree + tests
    - Maxim: GRASP over Inputhandler, write, draw, terminalapp +tests
    - Cas: sequence diagrams + tests suites

# guisseppe vragen
- moeten interfaces getest worden?
 # guisseppe commentaar
 - decouple the ui and view nog meer
	-> remove link between view and ui
	-> does observer really solves problems around coupling and cohesion?

~~- viewtree:
	node: children moet een list worden
	viewnode should not have children~~

- checking type of object is not good pratice!



# opgave

The main part of the presentation should cover the design. The motivation of
your design decisions must be explained in terms of GRASP principles. Use the
appropriate design diagrams to illustrate how the most important parts of your
software work. Your presentation should cover the following elements. Note that
these are not necessarily all separate sections in the presentation.
1. A discussion of the high level design of the software (use GRASP patterns).
Give a rationale for all the important design decisions your team has made.
2. A more detailed discussion of the parts that you think are the most interest-
ing in terms of design (use GRASP patterns). Again we expect a rationale
here for the important design decisions.
3. A discussion of the testing approach used in the current iteration.
4. An overview of the project management. Give an approximation of how
many hours each team member worked. Use the following categories: group
work, individual work, and study (excluding the classes and exercise ses-
sions). In addition, insert a slide that describes the roles of the team mem-
bers of the current iteration, and the roles for the next iteration. Note that
these slides do not have to be presented, but we need the information.
Your presentation should not consist of slides filled with text, but of slides
with clear design diagrams and keywords or a few short sentences. The goal
of giving a presentation is to communicate a message, not to write a novel. All
design diagrams should be clearly readable and use the correct UML notation. It is
therefore typically a bad idea to create a single class diagram with all information.
Instead, you can for example use an overview class diagram with only the most
important classes, and use more detailed class diagrams to document specific parts
of the system. Similarly, use appropriate interaction diagrams to illustrate the
working of the most important (or complex) parts of the system.




**vragen** voor Guiseppe:


//- trekken onze sequence diagrams (en klassediagram) op iets?
//- wanneer gaat verdediging zijn?
- inleveren: javadoc, diagrams, src-folder, **system.jar**?, (design.pdf)
- moeten we kant en klare GRASP uitleg hebben?
//- "*The number of files specified shall not be greater than the vertical size of the terminal text area (in characters) divided by two.*" Dees kan toch ni?!
//- case 5 alternative cases active
//- tereminal parser geript van Bart, is dat ok? indien ja, moet die dan in een aparte class of ni? (miss kan die mee in de algemene handler)
//- wat als statusbar niet past?

notes bij meeting:
- user mag geen activation bar hebben
- use case 4 filebuffer activation bar ends after saveinfile, how?
- system seq is user system interaction
- andere seq diagram is effectief met classes, we need to show everything, go more into detail, use entry point action from user as a given to start interaction
- rotate functionaliteit moet aangepast worden

to do:
- zorgen dat ons class diagram overeenkomt met de code
- sequence en class diagram fixen -> zie mail guiseppe

Tegen maandag
3) onderste scrollbar (optioneel)
4) Documentatie
5) Encapsulation enz (OGP)
8) rotate layout (victor)
10) default line seperator and flags
11) starten met minstens 1 file en max size_text_area/2
13) tests + defensive approach (throwing Exceptions etc)

mail Guiseppe

    Hi all,

    I will provide some tips regarding UML notation. For a discussion about your design, we
    can organize a meeting early next week.

    In the next points I will reference pages of the Larman book.

    - In you sequence diagrams, you are modeling both the interaction between external actors
    and the system, and the internal chain of events and messages exchanged by the software
    components following a request. You can use system sequence diagrams (page 175) to show
    the external actors, the events, and the generated output. So, you focus only on the
    dynamic behavior of the objects in the related sequence diagram of a use case (page 224).
    - Make sure to align the activation bars for method with the actual lifespan of the
    method call (usually, they do not start before a method is called, nor finish after a
    method returns).
    - Return arrows are usually dotted, while method calls are continuous, try to be
    consistent. Also, returning a value should not look like a method call.
    - Be careful when you have method calls that go back and forth in between classes. This
    is a sign of high coupling. In good design, method calls go typically (not always) point
    to the right while values are returned the opposite direction.
    - I assume Textr is the same as Main in your class diagram (?) Ask yourself how many
    responsibilities you are currently assigning to this class. 
    - Your composite relationship between main and layout is confusing. Do you want to say 
    that Layout can only be a part of Main?

    Best,
    Giuseppe

# GRASP

- **Information expert** (also expert or the expert principle) is a principle used to determine where to delegate responsibilities such as methods, computed fields, and so on.

    Using the principle of information expert, a general approach to assigning responsibilities is to look at a given responsibility, determine the information needed to fulfill it, and then determine where that information is stored.

    This will lead to placing the responsibility on the class with the most information required to fulfill it.
    
    *Related Pattern or Principle: Low Coupling, High Cohesion* 

- **Creator** 
    Which class is responsible for creating objects is a fundamental property of the relationship between objects of particular classes.
    
    Problem: Who creates object A?
    
    Solution: In general, Assign class B the responsibility to create object A if one, or preferably more, of the following apply:

    - Instances of B contain or compositely aggregate instances of A
    - Instances of B record instances of A
    - Instances of B closely use instances of A
    - Instances of B have the initializing information for instances of A and pass it on creation.
    *Related Pattern or Principle: Low Coupling, Factory Pattern*

- **Controller**
    The controller pattern assigns the responsibility of dealing with system events to a non-UI class that represents the overall system or a use case scenario. A controller object is a non-user interface object responsible for receiving or handling a system event.

    Problem: Who should be responsible for handling an input system event?
    
    Solution: A use case controller should be used to deal with all system events of a use case, and may be used for more than one use case. For instance, for the use cases Create User and Delete User, one can have a single class called UserController, instead of two separate use case controllers. Alternatively a facade controller would be used; this applies when the object with responsibility for handling the event represents the overall system or a root object.

    The controller is defined as the first object beyond the UI layer that receives and coordinates ("controls") a system operation. The controller should delegate the work that needs to be done to other objects; it coordinates or controls the activity. It should not do much work itself. The GRASP Controller can be thought of as being a part of the application/service layer (assuming that the application has made an explicit distinction between the application/service layer and the domain layer) in an object-oriented system with common layers in an information system logical architecture.

    *Related Pattern or Principle: Command, Facade, Layers, Pure Fabrication* 
    
- **Indirection** 
    The indirection pattern supports low coupling and reuses potential between two elements by assigning the responsibility of mediation between them to an intermediate object. An example of this is the introduction of a controller component for mediation between data (model) and its representation (view) in the model-view-controller pattern. This ensures that coupling between them remains low.

    Problem: Where to assign responsibility, to avoid direct coupling between two (or more) things? How to de-couple objects so that low coupling is supported and reuse potential remains higher?

    Solution: Assign the responsibility to an intermediate object to mediate between other components or services so that they are not directly coupled.
    The intermediary creates an indirection between the other components. 
    
    *Related Pattern or Principle: Controller*

- **Low Coupling**
    Coupling is a measure of how strongly one element is connected to, has knowledge of, or relies on other elements. Low coupling is an evaluative pattern that dictates how to assign responsibilities for the following benefits:

    - lower dependency between the classes,
    - change in one class having a lower impact on other classes,
    - higher reuse potential.

- **High cohesion** is an evaluative pattern that attempts to keep objects appropriately focused, manageable and understandable. High cohesion is generally used in support of low coupling.
    High cohesion means that the responsibilities of a given set of elements are strongly related and highly focused on a rather specific topic. Breaking programs into classes and subsystems, if correctly done, is an example of activities that increase the cohesive properties of named classes and subsystems.
    Alternatively, low cohesion is a situation in which a set of elements, of e.g., a subsystem, has too many unrelated responsibilities. Subsystems with low cohesion between their constituent elements often suffer from being hard to comprehend, reuse, maintain and change as a whole.
    
- **Polymorphism** 
    According to the polymorphism principle, responsibility for defining the variation of behaviors based on type is assigned to the type for which this variation happens. This is achieved using polymorphic operations. The user of the type should use polymorphic operations instead of explicit branching based on type.

    Problem: How to handle alternatives based on type? How to create pluggable software components?
        
    Solution: When related alternatives or behaviors vary by type (class), assign responsibility for the behavior—using polymorphic operations—to the types for which the behavior varies. (Polymorphism has several related meanings. In this context, it means "giving the same name to services in different objects".)

- **Protected Variations**
    The protected variations pattern protects elements from the variations on other elements (objects, systems, subsystems) by wrapping the focus of instability with an interface and using polymorphism to create various implementations of this interface.

    Problem: How to design objects, subsystems, and systems so that the variations or instability in these elements do not have an undesirable impact on other elements?

    Solution: Identify points of predicted variation or instability; assign responsibilities to create a stable interface around them.

- **Pure fabrication**
    A pure fabrication is a class that does not represent a concept in the problem domain, specially made up to achieve low coupling, high cohesion, and the reuse potential thereof derived (when a solution presented by the information expert pattern does not). This kind of class is called a "service" in domain-driven design.

    *Related Patterns and Principles: Low Coupling, High Cohesion.* 


# Sequence diagrams



**plant uml code use case 1: hey Victor dit is klaar**

MAIN
    
    @startuml
    actor User
    participant ":Terminalapp" as Terminalapp
    participant ":Inputhandler" as Inputhandler
    participant ":Files" as Files
    participant ":File" as FileBuffer
    participant ":ViewTree" as ViewTree
    participant ":Buffer" as Buffer

    User -> Terminalapp: launch(filepaths)
    activate Terminalapp
    Terminalapp -> Terminalapp: getTerminalSize()
    Terminalapp -> Terminalapp: check_for_flags(filepaths)
    Terminalapp -> Inputhandler: run(filepaths)
    activate Inputhandler
    alt valid file
    Inputhandler -> Files: new Files(filepaths, line separator, terminalsize)
    activate Files
    Files -> Files: inlezen(filepaths, line separator)
    Files -> FileBuffer: new file(file, line separator)
    activate FileBuffer
    FileBuffer -> FileBuffer: inlezen(file)
    FileBuffer -> Buffer: new Buffer(buffer)
    activate Buffer
    Buffer -> Buffer: setText()
    Buffer --> FileBuffer: return Buffer
    deactivate Buffer
    FileBuffer --> Files: return file
    deactivate FileBuffer
    Files --> Inputhandler: return files
    deactivate Files
    Inputhandler -> ViewTree: files.gettree()
    activate ViewTree
    ViewTree --> Inputhandler: return tree
    Inputhandler -> ViewTree: tree.getAllViewNodes().get(0).get_file();
    ViewTree --> Inputhandler: return active file
    deactivate ViewTree
    Inputhandler --> User: display()

    else file contains forbidden bytes
    Inputhandler -> Files: new Files(files, line separator, terminalsize)
    activate Files
    Files --> User: exception
    deactivate Files
    deactivate Inputhandler
    deactivate Terminalapp
    end
    @enduml
![case1](https://hackmd.io/_uploads/SkRLTabRp.png)





**plant uml code use case 2: klaar**
MAIN

    @startuml
    actor User
    participant ":Cursor" as C
    participant ":inputhandler" as UI
    participant ":viewTree" as V
    participant ":viewNode" as N
    participant ":File" as F

    User -> UI: press Ctrl+P or Ctrl+N
    activate UI
    UI -> UI: controlP(index,tree) or controlN(index,tree)
    activate UI
    UI -> V: tree.getAllViewNodes()
    activate V
    V-->UI: return viewNodes
    deactivate V
    UI->N: viewNodes.get(index).get_file()
    activate N
    N-->UI: return file
    deactivate N
    UI->UI: change Active
    UI-->UI: return index
    deactivate UI
    UI -> F: active.getCursor().getLine() and active.getCursor().getColumn()
    activate F
    F->UI: return line and column
    deactivate F
    UI->UI: moveCursor(line,column)
    UI-->User: display moved cursor

    User -> UI: presses arrow key
    UI -> UI: arrowDirection(myFiles)
    activate UI
    UI->F: active.getCursor()
    activate F
    F-->UI: return cursor
    deactivate F
    UI->C: cursor.moveDirection()
    activate C
    C->F: getBuffer().getvalues()
    activate F
    F-->C: return buffer values
    C->F: buffer.changeValues()
    deactivate F
    C->C: modifyOwnValues()
    C->UI: return 0 or 1
    deactivate C
    UI->Files: myFiles.display()
    deactivate UI
    activate Files
    Files-->User: shows updated screen
    deactivate Files
    deactivate UI
    @enduml

![case2](https://hackmd.io/_uploads/SJqB0pZAT.png)





**plant uml code use case 3: klaar**
MAIN

    @startuml
    actor User

    participant ":inputhandler" as UI
    participant ":viewTree" as V
    participant ":viewNode" as N
    participant ":File" as F
    participant ":Cursor" as C
    participant ":Write" as W

    User -> UI: press Ctrl+P or Ctrl+N
    activate UI
    UI -> UI: controlP(index,tree) or controlN(index,tree)
    activate UI
    UI -> V: tree.getAllViewNodes()
    activate V
    V-->UI: return viewNodes
    deactivate V
    UI->N: viewNodes.get(index).get_file()
    activate N
    N-->UI: return file
    deactivate N
    UI->UI: change Active
    UI-->UI: return index
    deactivate UI
    UI -> F: active.getCursor().getLine() and active.getCursor().getColumn()
    activate F
    F->UI: return line and column
    deactivate F
    UI->UI: moveCursor(line,column)
    UI-->User: display moved cursor

    User -> UI: presses arrow key
    UI -> UI: arrowDirection(myFiles)
    activate UI
    UI->F: active.getCursor()
    activate F
    F-->UI: return cursor
    deactivate F
    UI->C: cursor.moveDirection()
    activate C
    C->F: getBuffer().getvalues()
    activate F
    F-->C: return buffer values
    C->F: buffer.changeValues()
    deactivate F
    C->C: modifyOwnValues()
    C->UI: return 0 or 1
    deactivate C
    UI->Files: myFiles.display()
    deactivate UI
    activate Files
    Files-->User: shows updated screen, including scrollbar
    deactivate Files

    User -> UI: presses ASCII char
    UI->UI: writeKey(key)
    activate UI
    UI->W: addWrite(char, active)
    activate W
    W->F: getBuffer()
    activate F
    F-->W: return buffer
    W->F:modifyBufferValues()
    W-->UI: modified buffer
    deactivate F
    deactivate W
    UI->Files: myFiles.display()
    deactivate UI
    activate Files
    Files-->User: shows updated screen, including dirty asterix
    deactivate Files
    deactivate UI
    @enduml

![case3](https://hackmd.io/_uploads/SJJuZR-A6.png)



**plant uml code use case 4 hey dit is ook klaar Victor**

    @startuml
    actor User
    participant ":Inputhandler" as Inputhandler
    participant ":File" as FileBuffer
    participant ":Files" as Files
    participant ":ViewTree" as ViewTree
    participant ":ViewNode" as ViewNode
    participant ":Buffer" as Buffer

    User -> Inputhandler: Press Ctrl+P or Ctrl+N
    activate Inputhandler
    Inputhandler -> Inputhandler: ControlP(index, tree) or ControlN(index,tree)
    activate Inputhandler
    Inputhandler -> ViewTree: tree.getAllViewNodes()
    activate ViewTree
    ViewTree --> Inputhandler: return viewNodes
    deactivate ViewTree
    Inputhandler -> ViewNode: viewNodes.get(index).get_file()
    activate ViewNode
    ViewNode --> Inputhandler: return file
    deactivate ViewNode
    Inputhandler -> Inputhandler: change Active
    Inputhandler --> Inputhandler: return index
    deactivate Inputhandler
    User -> Inputhandler: Press(Ctrl+S)
    Inputhandler -> Buffer: getBuffer().getdirty()
    activate Buffer
    Buffer --> Inputhandler: dirty
    deactivate Buffer
    alt good
    Inputhandler -> Files: exists(file)
    activate Files
    Files --> Inputhandler: true
    deactivate Files
    Inputhandler -> FileBuffer: save()
    activate FileBuffer
    FileBuffer -> FileBuffer: write(line)
    FileBuffer -> Buffer: setdirty(false)
    activate Buffer
    deactivate Buffer
    FileBuffer -> FileBuffer: inlezen()
    FileBuffer --> User: display
    deactivate FileBuffer
    else bad
    Inputhandler -> Files: exists(file)
    activate Files
    Files --> Inputhandler: False
    deactivate Files
    Inputhandler -> Inputhandler: saveerror()
    Inputhandler --> User: error "Failed saving the file"
    end
    deactivate Inputhandler
    @enduml
![case4](https://hackmd.io/_uploads/r1_m8T-06.png)



**plant uml code use case 5: final**

    @startuml
    actor User
    participant ":Inputhandler" as I
    participant ":File" as V
    participant ":Files" as F
    participant ":FileBuffer" as FB
    participant ":viewNode" as N

    participant ":Viewtree" as T

    User -> I: press Ctrl+P or Ctrl+N
    activate I
    I -> I: controlP(index,tree) or controlN(index,tree)
    activate I
    I -> T: tree.getAllViewNodes()
    activate T
    T-->I: return viewNodes
    deactivate T
    I->N: viewNodes.get(index).get_file()
    activate N
    N--> I: return file
    deactivate N
    I->I: change Active
    I-->I: return index
    deactivate I
    I -> F: active.getCursor().getLine() and active.getCursor().getColumn()
    activate F
    F->I: return line and column
    deactivate F
    I->I: moveCursor(line,column)
    I-->User: display moved cursor

    User -> I: Press F4
    activate I
    I -> I: f4(tree, myfiles, running)
    activate I
    I -> V: Check_Dirty()
    activate V
    V --> I: dirty
    deactivate V


    alt Buffer is not dirty
    I -> V: close(active)
    activate V
    V -> T: removenode(active node)
    activate T
    T --> V: updated tree
    deactivate T
    V -> V: deelop()
    V--> User: updated view
    deactivate V
    I --> User: updated view

    else Buffer is dirty
        I --> User: ask confirmation
        User -> I: Press Y
        I-> F: exists(file)
        activate F
        F--> I: true
        deactivate F
        I-> FB: save()
        activate FB
        FB-> FB: write(line)
        FB-> Buffer: setdirty(false)
        activate Buffer
        deactivate Buffer
        FB-> FB: inlezen()
        FB--> User: display
        deactivate FB
        I -> V: close(active)
        activate V
        V -> T: removenode(active node)
        activate T
        T --> V: updated tree
        deactivate T
        V -> V: deelop()
        V--> User: updated view
        deactivate V
        I --> User: updated view

    else Buffer is dirty
        I --> User: ask confirmation
        User -> I: Press N
        I --> User: unchanged view
    end
    deactivate I
    deactivate User
    @endumlate User
        @enduml
![lLJ1Rjim3BthAuYU72pPgISVYZOP30GOZ1uo0piLGioqGXKfaEIqtTTFbDI4Tj8TbvD4FZu-YY--zq6wCEoraDjW7VpowCGXXjHM7QG9S5ElpM48BzBq6jqDI0_h2Q1H6bEYkvBmATDSoIo7tQumDij9_gZmhRLzfct59Dl5R72OiniXI3Gixc1Tmy6Xzx0AJdzx1ElogQNXr546ZDhN1R](https://hackmd.io/_uploads/Sy9ACa-Rp.png)



**plant uml code use case 6: final**

    @startuml
    actor User
    participant ":inputhandler" as I
    participant ":viewTree" as T
    participant ":files" as F
    participant ":debug" as D
    participant ":viewnode" as N

    User -> I: press Ctrl+P or Ctrl+N
    activate I
    I -> I: controlP(index,tree) or controlN(index,tree)
    activate I
    I -> T: tree.getAllViewNodes()
    activate T
    T-->I: return viewNodes
    deactivate T
    I->N: viewNodes.get(index).get_file()
    activate N
    N--> I: return file
    deactivate N
    I->I: change Active
    I-->I: return index
    deactivate I
    I -> F: active.getCursor().getLine() and active.getCursor().getColumn()
    activate F
    F->I: return line and column
    deactivate F
    I->I: moveCursor(line,column)
    I-->User: display moved cursor

    User -> I: Ctrl+R/Ctrl+T
    activate I
    alt not the last view in layout
    I -> T: rotate_counter/clockwise(node1,node2)
    activate T
    T --> I: updated tree
    deactivate T
    I -> F: deelOp(Terminalapp.getTerminalSize())
    activate F
    F --> User: updated view
    deactivate F
    else last view in the layout
    I -> D: testSound()
    deactivate I

    activate D
    D --> User: sound bell, unchanged view
    deactivate D
    end

    @end
    @enduml
![TLB1Rjim3BthAuYU72nPiHrz25eaC11Wy8hLsxLGBIuL9ak6HANRldwYuYoojrvacNnyVEJJNI3fAGv6o9wSXwy1lHXJIFTwb9RWfjPsZFGYhJBeRq06E2m09usldKVCoMwH_AuDXfnf5Xc5p_6OC_l_45gdpeIj42mADbiur31w305svCsx1t3-V6jPl3v9mgJjC25xPyaxyr1fg_3dcZ](https://hackmd.io/_uploads/Sy1d1CWRa.png)




# Class diagram
    
    @startuml
    class Main {
    - fileBuffers: List<FileBuffer>
    + launchTextr(filePaths: String[])
    + inspectBufferContents()
    + editBufferContents()
    + saveBuffer()
    + closeBuffer()
    + rearrangeLayout()
    }

    class FileBuffer {
    - filePath: String
    - contents: String
    - dirty: boolean
    + loadFile(filePath: String)
    + saveToFile()
    + isDirty(): boolean
    + closeBuffer()
    }

    class View {
    - buffer: FileBuffer
    + focus()
    + moveInsertionPoint()
    + updateScrollState()
    }

    class UserInputHandler {
    + handleUserInput()
    }

    class Layout {
    - bufferViews: List<FileBuffer> 
    + create_layout()
    }
    Main "1" -d- "0..*" FileBuffer
    FileBuffer "1" -l- "0..*" View
    Layout –* Main
    View "0..*" -l- "1"Layout
    Main – UserInputHandler
    UserInputHandler –> Main
    @enduml

![classdiagram2](https://hackmd.io/_uploads/Hki_r93nT.png)

