Using AbstractFactory I am a newcomer to design patterns. I read some articles about the abstract factory pattern, and wrote the following simple example:

public interface ParserFactory {
   List&lt;ITransport&gt; getBusList();
   List&lt;ITransport&gt; getTrainList();
   List&lt;ITransport&gt; getPlaneList();   
}


public abstract class XMLParserFactory implements ParserFactory{ }
public abstract class CSVParserFactory implements ParserFactory{ }

public class DOMTransportParser extends XMLParserFactory{

    public List&lt;ITransport&gt; getBusList(){ return null;  }
    public List&lt;ITransport&gt; getTrainList(){ return null; }
    public List&lt;ITransport&gt; getPlaneList(){ return null; } 
 }

 public class CSVTransportParser extends CSVParserFactory{

    public List&lt;ITransport&gt; getBusList(){   return null; }
    public List&lt;ITransport&gt; getTrainList(){ return null; }
    public List&lt;ITransport&gt; getPlaneList(){ return null; } 
 }

}


Is anything wrong with this code? Can it be improved? Do I understand the abstract factory pattern correctly?
This isn't really an Abstract Factory. Going on the theme of what you've got above (although I'm not sure what trains, planes and buses have to do with parsing!), an Abstract Factory would look something like the following:

public interface Parser
{
    List&lt;ITransport&gt; getBusList();
    List&lt;ITransport&gt; getTrainList();
    List&lt;ITransport&gt; getPlaneList();
}

public interface ParserFactory 
{
    Parser getParser();
}

public class XMLParser implements Parser
{
     //Implementation of Constructors and Interface methods from Parser
}

public class CSVParser implements Parser
{
     //Implementation of Constructors and Interface methods from Parser
}

public class XMLParserFactory implements ParserFactory
{
    public Parser getParser()
    {
        return new XMLParser();
    }
}

public class CSVParserFactory implements ParserFactory
{
    public Parser getParser()
    {
        return new CSVParser(); 
    }
}


This is then used in some way like the following:

public class Main
{
    //Note: Using a String is for illustrative purposes only. Ideally
    //it should be using some system or file setting. Half the point
    //of this pattern is that the caller doesn't know what kind of 
    //object they are getting back (which probably doesn't make too much
    //sense for parsers, really).
    public static ParserFactory createParserFactory(String type)
    {
        if(type.equals("XML") {
            return new XMLParserFactory();
        } else {
            return new CSVParserFactory();
        }
    }

    public Main(ParserFactory factory)
    {
        Parser parser = factory.getParser();
        List&lt;ITransport&gt; bus = parser.getBusList();
    }

    public static void main(String[] args)
    {
        new Main(createParserFactory("XML"));
    }


So what's the point of all this (it's quite a lot of code, after all). Well, firstly, it insulates the caller from knowledge of the concrete type. They don't know what kind of Parser they're getting back, the implementation details are hidden from them. Secondly, it localizes all object creation through a single point, which means client code will need very minimal updates when things change. For example, say we want to add a new kind of Parser - let's say a JSONParser - to our code. Then we create a factory and parser like we did previously:

public class JSONParser implements Parser 
{ // Implementation details 
}

public class JSONParserFactory implements ParserFactory
{
    public Parser getParser() { return new JSONParser(); }
}


Then we simply add it to our getParserFactory method:

    public static ParserFactory createParserFactory(String type)
    {
        if(type.equals("XML") {
            return new XMLParserFactory();
        } 
        else if(type.equals("JSON") {
            return new JSONParserFactory();
        } else {
            return new CSVParserFactory();
        }
    }


Note that any client code will be calling createParserFactory() and then getParser from that - so ideally, if they want to switch in a JSONParser, the only thing that needs to change in their code is the call to createParserFactory("JSON").

Hopefully this has cleared things up a little bit (and not confused you too much).