I am new to Design Pattern implementation and would like to strongly solidify my knowledge to become as good of a programmer as I can. Is this a proper implementation of the Abstract Factory design? The idea here is that I can interchangeably utilize either a ConsoleLogger or a FileLogger for three different “levels” of logging (Execution, Output, and Error). I want the client to be able to log Execution and Output to console, but Error logs to a file if necessary.
Logger Interface:
public interface ILogger { public void log(String content); }
Base Logging Factory:
import java.util.HashMap; public abstract class LoggingFactory { static { factoryMap = new HashMap<String, LoggingFactory>(); } private static HashMap<String, LoggingFactory> factoryMap; public abstract ILogger getLogger(); public static void register(String type, LoggingFactory factory) { factoryMap.put(type, factory); } public static LoggingFactory getFactory(String type) { return factoryMap.get(type); } }
ConsoleOutputLoggingFactory:
public class ConsoleOutputLoggingFactory extends LoggingFactory { static { LoggingFactory.register("ConsoleOutputLoggingFactory", new ConsoleOutputLoggingFactory()); } @Override public ILogger getLogger() { return new ConsoleOutputLogger(); } }
ConsoleOutputLogger:
public class ConsoleOutputLoggerimplements ILogger { @Override public void log(String content) { System.out.println("ConsoleOutputLogger " + content); } }
FileOutputLoggingFactory:
public class FileOutputLoggingFactory extends LoggingFactory { static { LoggingFactory.register("FileOutputLoggingFactory", new FileOutputLoggingFactory()); } @Override public ILogger getLogger() { return new FileOutputLogger(); } }
FileOutputLogger:
public class FileOutputLogger implements ILogger { @Override public void log(String content) { //write output to file } }
ConsoleErrorLoggingFactory:
public class ConsoleErrorLoggingFactory extends LoggingFactory { static { LoggingFactory.register("ConsoleErrorLoggingFactory", new ConsoleErrorLoggingFactory()); } @Override public ILogger getLogger() { return new ConsoleErrorLogger(); } }
ConsoleErrorLogger:
public class ConsoleErrorLogger implements ILogger { @Override public void log(String content) { System.out.println("ConsoleErrorLogger" + content); } }
FileErrorLoggingFactory:
public class FileErrorLoggingFactory extends LoggingFactory { static { LoggingFactory.register("FileErrorLoggingFactory", new FileErrorLoggingFactory()); } @Override public ILogger getLogger() { return new FileErrorLogger(); } }
FileErrorLogger:
public class FileErrorLogger implements ILogger { @Override public void log(String content) { //write error to file } }
Factory Initializer:
public class LoggingInitializer { public LoggingInitializer() { LoggingFactory.register("ConsoleOutputLogger", new ConsoleOutputLoggingFactory()); LoggingFactory.register("FileOutputLogger", new FileOutputLoggingFactory()); LoggingFactory.register("ConsoleErrorLogger", new ConsoleErrorLoggingFactory()); LoggingFactory.register("FileErrorLogger", new FileErrorLoggingFactory()); } }
Main:
public class AbstractFactoryExample { public static void main(String[] args) { new LoggingInitializer(); ILogger outputLogger = LoggingFactory.getFactory("OutputLogger").getLogger(); if (outputLogger != null) outputLogger.log("Hello World"); } }