views:

305

answers:

4

I am writing a quote-matching program in which two Abstract Factory Patterns are required, these are two interfaces; QuoteFactory and ModeFactory. ModeFactory switches between EasyMode and HardMode and QuoteFactory picks out Quotes between several different subjects (i.e. PoliticalQuotes, SportsQuotes). In short, the user will pick a mode, if the EasyMode is picked then the user has to guess the quote whereas if the user chooses the HardMode the user is told who said the quote and then has to guess, so the implementation of the Quotes will change depending on the Mode as well as the Quotes chosen.

So far I have created ModeFactory as an interface and implemented it into EasyMode and HardMode, but now I need to somehow integrate another Abstract Factory Pattern (or more) into these modes so that the Quotes can be chosen. If it is helpful I have also created a Quote class in which my Quotes are defined.

Can anyone help me come up with a basic implementation of these Abstract Factories? This is the outline of what I have so far, although I cannot help but feel that I have overcomplicated it somehow...

EDIT: To reclarify what I mean: If the user picks the Easy Mode then they are provided with the start of a quote AND the author of that quote, whereas if they pick the Hard Mode they are only provided with the start of the quote. For example

Easy Mode: "I felt the power of..." Jose Mourinho

Hard Mode: "I felt the power of..."

The hard mode does not give the author to make it harder for the user to guess the rest of the quote. Also, this is not a school assignment. I've been reading Head First Design Patterns and now I'm trying to apply what I've learned into different situations (instead of their Pizza example I'm working on a Quote Guessing Game, after reading through the QI (British TV Show) book.

public interface ModeFactory {
    public Mode retrieveMode(String s); 
}

public interface QuoteFactory {
    public Quote retrieveQuote(String s);
}
+2  A: 

Can you take one step back and restate what it is you are trying to do? I sometimes find that by going through the effort of explaining the challenge to someone not familiar with it, the solution emerges to me sort of organically.

From your descrpition, it seems like you have started with a partial solution ("I want to use an Abstract Factory pattern"), rather than starting with what you really want to do (eg, "I want to provide a quote class that delivers different quotes depending on Flavor (political, sports) and mode (easy, hard)") .

It feels to me like an enum, not a factory. There's an enum for {political, sports} and a separate one for mode.

EDIT: after thinking about this again, maybe it's a school assignment ("Use an abstract factory pattern to ....blah blah blah") and that is the reason you have sort of started with a half-solution.

Cheeso
It's not a school assignment. I'm working through Head First Design Patterns and instead of their Pizza examples I'm trying to create a Quote program in Java based on the quotes in my QI (British TV Show) book.
EnderMB
+2  A: 

You are probably over designing here. What you need first of all is a Quote class. This should encapsulate the quote and should have appropriate accessors (getters) both for Easy and Hard Mode. Then you need a collection of quotes. If these are persisted in a database, you can easily select the type of the quote.

I also think that the ModeFactory is unnecessary. Why you need an interface just to choose between two modes? A state flag is simpler.

kgiannakakis
+1  A: 

Seems to me like you're missing an important concept, a Question class. This is constructed with both a Mode and a Quote, can give out the right question and call tell you if the answer is correct:

public class Question
{
    public Question(Mode mode, Quote quote) { /* store these */ }

    public String getQuestion()
    {
        return quote.getQuote() + (mode == Mode.EASY ? quote.getAuthor() : "");
    }

    public boolean isCorrect(String answer)
    {
        return quote.getFullQuote().equals(answer);
    }
}

My idea here is that the Quote itself isn't really changing between Modes, just which parts of the Quote are presented to the user. With this approach, you can have one single repository of Quote objects that can be used anywhere by anyone. The Question is responsible for displaying the right amount of information to the user and deciding whether or not they have the right response.

Outlaw Programmer
I like this, and you *could* implement the "getQuote() + getAuthor()" etc as an abstract factory.
Cheeso
And yes, TofuBeer just did it!
Cheeso
+1  A: 

Without too much thinking, and trying to keep to your design, how about something like this (I assume that the Quote class has getText() and getAuthor methods, also you might want to make it getText(int numberOfWords) so you can configure how much of a quote to give):

public enum Mode 
{
    EASY,
    HARD,
}

public enum Category 
{
    SPORTS,
    POLITICS,
}

public abstract class QuoteFactory 
{
    public QuoteFactory getQuoteFactory(final Mode mode)
    {
        // return either the Hard or Easy QuoteFactory
    }

    public abstract Quoute getQuote(Category category)
}

class HardQuoteFactory
    extends QuoteFactory
{
    public Quote getQuote(final Category category)  
    {
         // ...
    }
}

class EasyQuoteFactory
    extends QuoteFactory
{
    public Quote getQuote(final Category category)  
    {
         // ...
    }
}
TofuBeer
Just implemented it and it works perfectly. Thank you!
EnderMB