Skip to content

Latest commit

 

History

History
68 lines (43 loc) · 15.3 KB

DESIGN.md

File metadata and controls

68 lines (43 loc) · 15.3 KB

Design Document

Kei Yoshikoshi, John Gilhuly, Georgia Tse, Catherine Zhang

###Introduction (Kei)

Our team is trying to implement an general IDE that is able to interpret simple Logo language and simulate a simple Logo program. This engine consists of a GUI that gives users a variety of options on how to control the turtle on the screen, and allows the user to input commands given a certain syntax. These commands are not only limited to those that affect the turtle on the screen, but can also calculate different things. The primary design goals of this project is to separate the front-end (the GUI) and the back-end (the model) so that group members can work on these parts separately without affecting each other's code. We will also design the project in such a way that it is easy to implement new features, such as new commands, new turtles, etc. As stated, modification of the back-end from the front-end side will be closed, and vice versa. Each side will only know what is completely necessary, and all other processes are hidden. This makes extensions easier - if we were to change the front-end to some other type of display, this should be rather easy since the back-end would not be affected (open for extension, closed for modification). We intend to implement the above in a scalable manner that conforms to standard design conventions separating the program into reasonable structures using various classes. We will be using Java8 and JavaFX to do so.

###Overview (Kei)

The class that will jump start the entire program is the Main class. This is quite standard for any Java program - it will have a start method that is called by a main method. This main class will call the Controller class. Before we get into the details of these classes, I will explain our approach for this project. We are using two design patterns from oodesign.com - Model View Controller (MVC) Pattern and Observer-Observable Pattern. We felt that these two patterns were appropriate for our project since we do have a model (back-end) and a view (front-end). The controller can send commands to the model to update the model's state and also can send commands to the view to update the view. For this project, we are primarily using the MVC Pattern to funnel information from the front-end to the back-end, since the user will interact with the GUI and that has to be reflected in the back-end. The Controller also has access to the Parser, which takes in some string of commands and returns one, or a series of Command object, which are categorized into different subclasses, which may have more subclasses. For the moment, we are thinking of having a module class for 'Move' commands, 'Math' commands, etc.

In terms of the Observer-Observable Pattern, the Observer will be the View (SceneUpdater) and the Observable will be the TurtleModel (the model that contains the virtual turtle). To do this, the SceneUpdater will implement Java's Observer class (or we may create our own, depending on what we need to pass). This class will have an update method that will be called once the Observable has a change. In the Observable side, the TurtleModel class implements Java's Observable class. This class will then use the method 'notifyObserver(....)' to pass in some parameter or information to the Observer. The Observer will then take in this information via the 'update(Observable obj, Object args)' method. This pattern serves as a way for the back-end to pass information to the front-end without having to instantiate a front-end object in the back-end and vice versa. Of course, the Controller class will instantiate both the SceneUpdater and TurtleModel classes, and, using the method addObserver, will attach the Observer to the Observable.

For the front-end specifics, the SceneUpdater will control the GUI class. We plan for this class to contain the important GUI elements such as buttons, TurtleView, Nodes, Menu, Canvas, etc. We are going to use this class to store these elements and give SceneUpdater the control to edit these objects (such as draw a line, change color, change images, change background, etc). This way, the GUI class will not be a mess of methods creating these JavaFX objects as well as editing them. The GUI class will also have access to the turtle's image. Given the information passed from the back-end via the Observer-Observable pattern, we will move this image accordingly. This will be put in a class called TurtleView, which contains the image, the color, the usage of the pen, invisibility, and other methods that allows these variables to be retrieved/modified. We are also planning to have a class for the HTML page, which we have not fully discussed yet. For now, the order of action is as follows: the GUI takes in the command, the command is passed to the controller who gets back a command object from the parser, this command object is passed to the back-end, the back-end notifies the observer that a change had been made after the virtual turtle had been moved or other operations had been done, and the GUI takes this information from the SceneUpdater to display it.

Major components of the back-end include the Model class and TurtleModel class, which could possibly contain the x and y coordinates of the turtle and its heading (with 0 degrees being North). We could also have other characteristics of this turtle in this class, such as the speed of its movement. This class will also have a getLocation() method, which, as the name suggests, returns the location, most likely using a Pair class (a class that we will make which contains the coordinates x and y). Another element of the back-end include modules classes that are abstract enough to encapsulate behaviors of all specific commands. Although we have not discussed the specifics for the back-end classes, some ideas include creating a data structure to keep track of the commands that were passed in and created, a data structure to keep the variables created, a data structure to keep the turtles for potential multiple turtles for the extension. These data structures will be kept in Model, which makes it convenient for Model's update() method to update the values of these commands/variables through executing new Commands. A bonus feature that we're considering implementing is allowing for the "animation" of a Turtle's movement. This would involve using a Timeline to frame actions for 'move' commands. Forward 50 would mean the action Forward 1 repeats 50 times, which would allow the Turtle to move easily in 'real-time' when the front-end updates Turtle's location at each frame.

Design OverView Drawing

###User Interface

The user interface would contain a menu bar (to contain personalization of the pen, turtle, background color, access to a help page), a text input area (for commands), a console for return values, a sidebar to see previous commands, and the physical canvas/grid. The menu bar will also be used to incorporate additional requirements in the next sprint. The text input area will support commands in a number of different languages, using resource bundles. Lastly, the user will be able to select previous commands in order to run them again.

![UI Picture.JPG] (https://github.com/duke-compsci308-spring2015/slogo_team06/blob/master/UI%20Picture.JPG)

###Design Details

The relationship between the view and the controller would be one way, any commands, or anything that needed to be passed to be interpreted would go to the controller that would then parse the commands and get the appropriate command class or update the appropriate turtle, etc. Any updates to the back end turtle classes would be observed by the view updater that would update instantly. This way, the model could relay information back to the view in this way. This way, the model needs to contain an observer instance of the view updater.

The Model itself will contain methods such as update(), which call commands instantiated by the parser. It will also contain data structures that keeps track of called commands and created variables. The command parser, which currently resides in the Controller/middle ground, would parse the given String command returns an (or a series of) Command object(s), depending on regex parsing using a customized properties file. A general abstract commandsuper class have sub command types so that each command could be generalized into a module, whether it is a math type command, or turtle status command, or a move command, and within those subgroups, some commands would have its own class, but extend these super class. For example, the parser is able to determine that FD 50 is a Move command that takes in parameters (current Direction of Turtle, 50 units), and instantiate the Move. Defining specific commands as more generalized modules will allow us to implement new and related commands without adding an additional class for each new command. Our current design also assigns the Parser the responsibility of distinguishing whether the command should be processed by the back-end or directly by the front-end. If it was a view type command, the controller would call on the view to perform the specified command, and if it was a non-view related command, it would call the model classes to reflect that command change.

On the front-end side, the three main classes are SceneUpdater, TurtleView and GUI. The SceneUpdater will handle any logic or computation that needs to be done by the front end, for example loading an image file for a new turtle image. Additionally it will handle any updates to the GUI. This class will listen to the TurleModel class, and use any changes to that class in order to update the view. The GUI is simply a collection of Nodes, including a canvas, a text input, a menu bar, and a panel of previous commands. This class will be updated by SceneUpdater. Lastly, the TurtleView will act as a container for various visual attributes of the turtle. These include the image file of the Turtle, the color of the Turtle's pen, etc. None of these classes will directly contact the backend, and only the SceneUpdater will interact with the Controller. Currently, View also holds an update() method that handles view-associated commands.

###API Example code (this is especially important in helping others understand how to use your API) It should be clear from this code which objects are responsible for completing each part of the task, but you do not have to implement the called functions. Show actual "sequence of code" that implements the following use case: The user types 'fd 50' in the command window, and sees the turtle move in the display window leaving a trail. Note, clearly show the flow of calls to public methods needed to complete this example, indicating which class contains each method called. It is not necessary to understand exactly how parsing works in order to complete this example, just what the result of parsing the command will be.

  • If the user typed in 'PENDOWN', this command would go through the command parser, and it would see if it is a subtype of a view command and either call the scene updater directly to change the value of the pen status and have the view display the return value.
  • If the user typed in 'fd 50' this command would be passed to the controller and then it would give it to the command parser. The command parser determines that is a move sub-type command. The command is called and the value of the turtle's location is updated. The view, which observes turtle's change, will display the returned value, reflecting a change in the turtle's locaiton.

###Design Considerations

We talked about having a turtle view and a turtle model, where the turtle view is the image and any pen drawing methods, and the turtle model contains the x and y locations and store the heading. We considered where the responsability of storing the offset grid view where the back end will send original locations and final locations and the view will store things like if the pen is up/down to interpret whether or not to draw the line. We also considered where the command parser should live / be stored either between the controller and the model, and act as the other middle man between the view and the data. We disliked the idea of having the view contain a method in the controller, but then couldn't come to a medium between using an observable and having the controller shuttle information back and forth. A huge consideration we had was how exactly to use the obeservable in our turtle classes because we ran into complications with the physical drawing of a line which requires a starting and ending point. If you used the observable, the view turtle would need to have the old position, but once the model turtle was changed, the view turtle would have no idea where it used to be.

An alternative to using the observable is to just have the back end turtle send information about where a line needs to be drawn/ where a turtle needs to be moved so that given original positions and new positions. This way, the front end turtle does not need to store its location, but just know have a move method, and based on if the pen is up or not, it will draw a line. <-- we are not sure about the best way mediate between these options. If we made commmands classes, there was also a problem where it needed to be able to modify the turtle directly, but the command class couldn't have an instance of the turtle so then what is even the purpose of the separate command class? Would it be appropriate of the instance of the turtle (say, View's front-end turtle) is created in the View?

Another design element that we're considering is the use of expression trees to help interpret commands that contain subcommands (for example, fd sum 10 20). Ideally, the parser will be constructing one expression tree for each command. The expression tree will then be traversed recursively with each node in the expression tree being one sub-command. The final value of the command will be returned in the value of the parent node of the tree. Whether using this design structure is a good idea is dependent on where the parser is stored and where the tree is traversed.

A potential disadvantage of sending commands to either front-end or back-end to process is the added difficulty on the parser to separate out which commands are front-end and back-end. We project that some sort of if-statements will be needed in the Controller, and new commands will either be sent to the View's or Model's update() methods. A simplification of this is to have all commands sent to the back-end. It reduces the need for if-statements, reduces the redundancy of having two update() methods, and lastly, it accounts for potential commands that contain sub-commands that both previously sent separately to front-end and back-end.

###Team Responsibilities

Front end: John, Kei

  • GUI
  • Parser
  • View updater class Secondary Responsibilities: Controller

Back end: Catherine, Georgia

  • Command class & modules classes
  • TurtleModel class Secondary Responsibilities: Parser

Generally, John and Kei will work on the GUI and the command parser, where as the back end would be Catherine and Georgia to connect the commands of the turtle to its visual counterpart. For Sprint 2, the idea is to have basic components for each front-end and back-end implemented, and implement, as a group, a simple Controller that will connect both parts together. We will then continue to implement more features with our sub-group members before reconvening.