DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Poor Man's Console MVC

As MVC has gotten more muddled, it's important to remember that there should be a clear connection between controllers and concepts.

Grzegorz Ziemoński user avatar by
Grzegorz Ziemoński
·
Apr. 21, 17 · Tutorial
Like (5)
Save
Tweet
Share
17.17K Views

Join the DZone community and get the full member experience.

Join For Free

After two posts of pure theory about the MVC Pattern Language, I was looking to provide some practical examples. The technical part is easy – everybody already knows how to implement that in various ways, but I couldn’t figure out how to show the whole mental models part of it. In the end, I came up with what follows – an MVC “Pet Clinic” in the console!

As we learned in the previous posts, on the idea level, MVC is most concerned with understanding the user’s way of thinking. Therefore, we won’t jump straight into code here. Instead, we’ll visit a real pet clinic on the outskirts of your town and watch our user at work.

She Ain’t a Computer Lady

The clinic that hired you is actually a small office that consists of a few rooms, the most important being the visiting room. The old lady that runs the place has no computer at the moment and you keep wondering why does she want to pay so much money for dedicated software. After a while, you conclude that this is exactly the kind of person who needs a dedicated piece of software. If you tried to give her the Spring’s Pet Clinic and call it a day, she’d be totally lost in it. You need to create a habitable environment for her, as she’ll be learning both using the computer and your program at the same time.

Gathering Requirements

Instead of acting like an idiot and asking the old lady for the “requirements” directly, you sit quietly and watch her work for a few hours. This gives you a pretty good idea of her workflow.

She keeps track of all her visits inside a calendar. When somebody calls to schedule a visit, she asks about the person’s name, pet names and preferred visit time. Then, when both sides agree on the time of the visit, she notes it down in her calendar.

When the visit time comes, the old lady takes out pets’ files, which contain all important information about their health history. Then she takes care of the pet itself. Not much interesting stuff here. She makes the same “you’re so lovely” face every time and solves all kinds of problems – from a pet being actually sick to being moody and not wanting to play with its owner (sigh). After she finishes the “care-taking” stuff, she sits down and writes a short summary of the visit. The summary consists of two parts – course and recommendations. She always writes down two copies – one for the owner and one to put in the pet’s file.

Modeling the Domain

You tried talking to the woman about the veterinary domain but it seems that talking to her about abstract terms and relationships is as productive as talking with you about Malaysian poetry of the 19th century. Luckily, the concepts behind scheduling a visit seem easy enough to create the first prototype without creating an advanced domain model. You start off with something like this:

What’s in the Lady’s Head?

As we said before, simply creating a CRUD for visits, pets, and owners is not enough. We want better than this. Therefore, we have to look for things that will make the user instantly familiar with our software; something that improves his workflow instead of completely turning it around. In the case of our vet lady, these things would be the visit calendar and the pet files.

The physical calendar that the lady uses looks like a big notebook in which every two pages represent a single week. When a visit is scheduled, she notes things down using a specific format: hour goes first, then the owner’s name and the pets in the end.

The pet files are cardboard folders containing all of the summaries from the previous visits and occasionally some other medical documentation. The old lady keeps them in a desk’s locker, sorted alphabetically so that she can find the right one faster when the visit starts.

Implementing a Visit Calendar

The visit calendar will become a business object in our system. Since there will be quite a lot console printing and input parsing, we’ll separate it into the famous MVC triplet: model, view, and controller. This triplet should work together to give the lady a feeling that she’s working with her old calendar, just that the calendar is now computerized. Therefore, we’ll keep the weekly grouping of visits and allow her to switch the weeks like she’d be flipping pages in her old calendar. We’ll also print the visit information in a format similar to the one she used in her old calendar. I did some basic implementation, let’s take a look at it.

Controller

So far our controller recognizes three commands: “next” and “previous”, which change the calendar’s week, and “add”, which allows for adding a visit to the calendar:

public class VisitCalendarController implements Controller {
    // field, c-tor

    public boolean execute(String command) {
        if ("next".equals(command)) {
            visitCalendar.nextWeek();
            return true;
        }
        if ("previous".equals(command)) {
            visitCalendar.previousWeek();
            return true;
        }

        if (command.startsWith("add")) {
            parseAdd(command);
            return true;
        }

        return false;
    }

    // parseAdd method
}

Model

The model is responsible for holding the information about the currently selected week and allows manipulating the underlying visits. By the means of changed() method, it lets the view know whenever something changes in the calendar:

public class VisitCalendar extends Model {
    static final DayOfWeek[] OPEN_DAYS = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};

    private Week currentWeek;
    private Visits visits;

    // c-tor

    Week getCurrentWeek() {
        return currentWeek;
    }

    void nextWeek() {
        this.currentWeek = currentWeek.next();
        changed();
    }

    void previousWeek() {
        this.currentWeek = currentWeek.previous();
        changed();
    }

    List<Visit> visitsOn(DayOfWeek day) {
        return visits.on(currentWeek.get(day));
    }

    void addVisit(DayOfWeek dayOfWeek, LocalTime time, String ownerName, String[] petNames) {
        // stuff
        changed();
    }
}

View

The view displays weekly visits in a format similar to the one already used by the vet lady and accepts user’s commands:

public class VisitCalendarView implements View {
    // fields, c-tor

    public void modelChanged() {
        show();
    }

    public void show() {
        show(visitCalendar.getCurrentWeek());
        for (DayOfWeek day : VisitCalendar.OPEN_DAYS)
            show(day);
        askForCommand();
    }

    private void show(Week week) {
        System.out.println(week.getStart() + " - " + week.getEnd());
    }

    private void show(DayOfWeek day) {
        System.out.println(day + ":");
        show(visitCalendar.visitsOn(day));
    }

    private void show(List<Visit> visitsOnDay) {
        if (visitsOnDay.isEmpty()) {
            System.out.println("No visits!");
        } else {
            visitsOnDay.forEach(this::show);
        }
    }

    private void show(Visit visit) {
        System.out.println(visit.getTime() + ": " + visit.getOwnerName());
        System.out.println("Pets: " + visit.getPetNames());
    }

    private void askForCommand() {
        try (Scanner scanner = new Scanner(System.in)) {
            String command;
            do {
                command = scanner.nextLine();
            } while (!controller.execute(command));
        }
    }
}

Conclusion and Next Steps

That’s everything I did in this prototype so far. The whole source code is available here. As you probably noticed, there’s no technical rocket science in there and not even any new concept at the first glance. I think the most important thing about this example is that the user is communicating directly with the business objects. She’s not talking to some generic  VisitController, which talks to some generic  VisitService. Instead, we’re exposing her to communication with an object she already knows – the  VisitCalendar.

In the next post, I’ll try to move our visit calendar to the web and we’ll see how the concept of business objects plays with “so-called” Web MVC frameworks like Spring MVC. If I have enough time (which is unlikely, but possible), I’ll try to add the second business object to the system – the pet files. Obviously, if someone from the readership wants to try their strengths in doing that, pull requests are welcome!

Calendar (Apple) Console (video game CLI)

Published at DZone with permission of Grzegorz Ziemoński, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Shift-Left: A Developer's Pipe(line) Dream?
  • Integrate AWS Secrets Manager in Spring Boot Application
  • How To Create a Failover Client Using the Hazelcast Viridian Serverless
  • Intro to Graph and Native Graph Databases

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: