2

I recently worked on a file explorer within a console window (like Midnight Commander). I want to use ncurses as library. I have encountered some fundamental problems with my design and searched on the Internet for solutions and better practices.

However I ended up scrutinising my whole programming work and my approach to problems. I have always stuck to Singletons and started to develop a pattern, that uses different Managers to complete different tasks, that should be separated (e.g. Database, GUI, Networking). I read on the Internet and heard from colleagues, that Singletons are bad and that I should stop using them. I was able to use static references to access the managers.

So the basic structure of my problem is like this:


DirectoryController
One instance (or tab) that contains files and a path It is like the logical representation of a file view

DirectoryManager
Manages all the directory controllers

GUIManager
Manages the GUI and needs somehow access to the current directory controller (Most likely over the DirectoryManager)

KeyboardManager
Gets input of the user Uses the dir controller to update path and move current selected files


I want to separate these functionalities, because I think it is better to separate different tasks into task groups.

Maybe I am doing something wrong but I just can't think of a different solution, how to split up these functionalities and still be able to use functionalities of another group :/

Edit:
I have the same problem with libraries like FLASK for python. How am I supposed to store and access shared data when all of the FLASK functions and all of the REST endpoints are static functions? I think that I somehow have to have a object, that is accessible by all of these functions. But I cannot think of a solution for this either.

3 Answers 3

1

I have no familiarity with Flask, but I can clarify one thing: Singletons are no more nor less inherently bad than anything else. However, for a Midnight Commander clone, your "directory controller" at least should NOT be done as a singleton, because you will be using two of the panes. Correspondingly, regardless of what exactly they do, there should be two instances. It is not the use of singletons that is bad, but instead the use of singletons when it doesn't make sense.

As for your directory/gui/keyboard managers, these do not inherently need to be distinct things. If you're trying to implement by way of REST-style functions, then I'll suggest keeping the following in mind:

  • The file system you're interacting with is essentially a Model in the MVC sense.
  • If you're running this with separate client & server portions communicating only via RESTful interfaces, then inherently you'll have to have the client provide some data to the server with essentially every request. In HTTP, the client has to e.g. tell the server what action it wants done, as well as things such as which resource it wants these things to be done in regards to. Your file manager would, for example, need to specify the action, and two file name/path sequences.
  • Remember that REST style interfaces are mostly for networking with somewhat intermittent protocols, such as HTTP. Also bear in mind that the "statelessness" is only true in the context of the actual protocol, between individual connection sessions. While a particular connection is held open, state describing that connection is maintained; similarly, while while the state describing a connection is discarded when a connection is closed, state associated with whatever was using the connection is not required to be deleted in order to keep the protocol stateless. HTTP is a perfect example, as HTTP itself is stateful within an individual connection (e.g. HTTP 1.0 vs 1.1 vs 2.0), stateless between connections (if you close a connection, then you have to renegotiate everything if you open it back up), and the "applications" (e.g. the World Wide Web) that use it are allowed to themselves maintain state (e.g. cookies).
1

You don't really need any singletons here, you can just use composition to build up your structure. Also, you have a bunch of Controller and Manager classes but you're missing the fundamental concepts that they're trying to model. I would start with something like this:

  • A Directory class that represents a directory in the filesystem. It contains a path and operations to list files, copy, move etc. This abstraction also lets you expand the concept of directories in the future (such as remote filesystems).
  • A DirectoryPane class that represents a pane in the UI. It contains a Directory instance and UI-specific properties such as the currently selected file.
  • A FileExplorer class that contains two DirectoryPane instances (since you're building something like Midnight Commander).
  • A FileExplorerWindow that wraps a FileExplorer instance and interfaces with ncurses to process user input and render the UI.

Your application's main function simply needs to construct a FileExplorerWindow and get it going. There are no singletons involved, and you can easily extend this design to support multiple windows at once, more than two panes per window, or panes of different types.

-1

I had the exact same questions about a year ago and from experience I can tell you that a really good way to deal with it is to go functional. Basically you should have a single function for each separate single task. Just create what you need and give names based on the goals without noun-ifying. Then it will quickly become apparent what can be grouped how. This will enable you to assemble these basic building blocks into bigger things you might call operations. Operations, then, can be composed into services and so on. It's very tempting to use inheritance in an OO world, but composition goes a much longer way.

This is a great video about the topic https://youtu.be/srQt1NAHYC0 and worth every second of it. It's about how F# solves all of these problems and more. I sincerely encourage you to try it (or Haskell, though it's a little harder).

1
  • Inheritance isn't actually mentioned in the question. Furthermore, objects allow composition just as easily as functional programming, and nouns are needed in functional programming just like verbs are needed in object-oriented programming.
    – aerohammer
    Commented Mar 3, 2019 at 3:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.