Source code consists of a set of interfaces which form the model of an undo-manager for a text editor.
The exercise consists in implementing the interfaces UndoManager and UndoManagerFactory, including unit tests.
The other interfaces should be used "as is" - i.e. the implementation of UndoManager and UndoManagerFactory should not rely on any specific implementation of the other interfaces.
You are free to use third-party software libraries in your solution if you want.
Implemented UndoManager
and UndoManagerFactory
interfaces.
Created TextEditorModule which is the root module and in real application would consist of all submodules & configuration existing in the application.
Tested solution with unit tests.
- Why I chose
CircularFifoQueue
instead ofQueue
andDeque
?Queue
, depending on implementation, could be faster thanDeque
as it is just "one-sided" andCircularFifoQueue
perfectly fitsDefaultUndoManager#registerChange
requirements - when the queue is full, oldest element should be replaced.
- Why
Change
andDocument
are moved to separate packages?- I believe that
Change
andDocument
are logically separate from UndoManager and can exist without it
- I believe that
- Why use Guice Dependency Injection framework?
- Because it is lightweight and helps to separate logical modules and that way introduces loose coupling
- Easy to switch implementations
- Why there are no comments in the code?
- I believe that code should be self explanatory without the need of comments explaining what certain thing does. I usually try to write code in the way that a person without IT knowledge could read it and understand the concept of what is happening.
- Clean up
DefaultUndoManager
by splittingUndo
andRedo
functionality into two different classes so each class does just one thing, however they would still be quite tightly coupled because of Undo<~>Redo connection. - Split functionality in the way that can help test values of
Undo
andRedo
actions easily.