Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am working on an application in C# and I am having some extreme difficulty solving this design issue.

Basically the application allows users to create cook books. A user can click "new book" and the application will create a book with a given name. Now the user is allowed to add "recipes" to that book. The user can save the book at any time. They can load this book on other computers with the application. Only one book can be open at a time in the application. So if they user wants to create a new book or open a different book, the application will need to close the current book and then open the next book.

My question is, what would be the best way to solve this problem?

  • How would I check if a book is open?
  • How would I have the application create the new book?
  • How would I have the application "close and forget" the book that was closed, so that the only open book is the new one?

What I was thinking is that I would have a CookBook class and a Recipe class. The CookBook class would hold the information pertaining to the new book that was created and it would hold a list of all the recipes in that CookBook. I am just having a hard time figuring out the best way to give the user the ability to create a new CookBook and close the current cook book so the user can create a new one.

The CookBook class will have a function that wil write the contents of the CookBook and the recipes of the CookBook to a file. There will also be a function in CookBook that will populate the application's user interface based on the contents of a CookBook that is loaded/opened by the user.

share|improve this question
add comment

2 Answers

Usually these kinds of things are done with a small database. Not only does using a database mean that you don't have to worry much about keeping track of file states, you can do searches, detect duplicate recipes, all that neat stuff that you will have to code yourself.

If you really want to do it all yourself, add a BookShelf class that's responsible for knowing about all the cookbooks. You ask the BookShelf to get a book down for you (open), put the book away, and the BookShelf will handle all the details of create, open and closed.

Later, if you do move to a database, you can make the BookShelf handle all the DB operations and you're already nicely setup.

As for saving, you should either save a recipe whenever a change is made and you leave the page and also give a button to allow the user to save manually (it makes them feel better) whenever they want.

share|improve this answer
    
If there is a requirement to only ever have 1 cookbook open at a time, why have a bookshelf? –  Steve Evers Jul 17 '11 at 23:47
    
So the bookshelf can control access to that one book, automatically close the existing one when a new book is asked for, and generally hide away the code involved. You need code for it somewhere, might as well make a class out of it and not dirty up all your GUI code with data management details. Besides, a bookshelf also works as an abstraction of a bunch of book to choose from, when opening that single one. –  Patrick Hughes Jul 18 '11 at 3:34
add comment

The idea of a cookbook is a good one. It sounds like your application will operate much the same a word document (wrt to file lifecycle).

Create your cookbook object and have one at the relative root of your application (the root form, I imagine, not Program.cs). "currentCookBook" sounds about right.

How would i check if a book is open?

You know whether or not a user is working in an open cookbook in one of two ways:

  • if (this.currentCookBook == null) { /* no cookbook is open */ }
  • if (this.currentCookBook == CookBook.NullObject) { /* null-object pattern */ }

How would I have the application create the new book?

Easy peasy:

this.currentCookBook = new CookBook(); // or = CookBook.Empty;

How would I have the application "close and forget" the book that was closed, so that the only open book is the new one?

Make an object that is responsible for the IO of cookbooks.

internal CookBookIO
{
    public static void Save(CookBook cb, string filename) 
    { 
        /* writes cookbook to filename */
    }

    public static CookBook Open(string filename)
    {
        CookBook cb = new CookBook();

        /* read file and populate cb */

        return cb;
    }
}

Open a cookbook like so:

using (OpenFileDialog ofd = new OpenFileDialog() { /* properties */ })
{
    if (ofd.ShowDialog() == DialogResult.Cancel)
        return;

    this.currentCookBook = CookBookIO.Open(ofd.Filename);
}

... and save (and close) it like so:

using (SaveFileDialog sfd = new SaveFileDialog() { /* properties */ })
{
    if (sfd.ShowDialog() == DialogResult.Cancel)
        return;

    CookBookIO.Save(this.currentCookBook, sfd.Filename);
    if (saveAndClose)
    {
        this.currentCookBook = null; 
        // or this.currentCookBook = CookBook.NullObject;
        // or this.currentCookBook = CookBook.Empty; if you want to have it 
        // default to a new, open book upon saveAndClose
    }
}
share|improve this answer
    
This is exactly what i was thinking! However, i did not think about the cookbookio, that is gold. Thanks for the information. I will accept an answer after i see more opinions. Thanks again. –  prolink007 Jul 18 '11 at 0:20
    
How do you know if the cook book file is open by another app? –  Morons Jul 18 '11 at 1:25
    
@Morons: It would be no different than any other type of file. I omitted error handling here for brevity and readability. –  Steve Evers Jul 18 '11 at 1:30
    
@snorfus: "Create your cookbook object and have one at the relative root of your application (the root form, I imagine, not Program.cs). "currentCookBook" sounds about right." In response to that comment... i have a CookBook class and a Recipe class and a MainForm class. Are you saying that i would declare the cookbook object in the mainform class? Should i use a singleton pattern here? Would that be the best approach? –  prolink007 Jul 19 '11 at 1:22
    
@prolink007: I get the impression that programming is new for you, so for the moment, keep it simple. MainForm appears to be a reasonable place for it. Keep in mind that as your program progresses and you add complexity that you will likely want to consider refactoring to a pattern that decouples your form from the logic behind it (MVC/MVP/MVVM). –  Steve Evers Jul 19 '11 at 4:12
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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