1
\$\begingroup\$

I implemented the Abstract Factory design pattern as follows.

Concrete Implementation

interface VideoExporter {
    void exportVideo();
}

interface AudioExporter {
    void exportAudio();
}

class HQVideoExporter implements VideoExporter {
    @Override
    public void exportVideo() {
        System.out.println("Exporting HQ video");
    }
}

class HQAudioExporter implements AudioExporter {
    @Override
    public void exportAudio() {
        System.out.println("Exporting HQ Audio");
    }
}

class LQVideoExporter implements VideoExporter {
    @Override
    public void exportVideo() {
        System.out.println("Exporting LQ video");
    }
}

class LQAudioExporter implements AudioExporter {
    @Override
    public void exportAudio() {
        System.out.println("Exporting LQ Audio");
    }
}

enum QUALITY_TYPE {
    LOW, HIGH
}

Factory Class

class ExporterFactory {
    static VideoExporter createVideoExporter(QUALITY_TYPE quality_type) {
        return switch (quality_type) {
            case LOW -> new LQVideoExporter();
            case HIGH -> new HQVideoExporter();
        };
    }
    static AudioExporter createAudioExporter(QUALITY_TYPE quality_type) {
        return switch (quality_type) {
            case LOW -> new LQAudioExporter();
            case HIGH -> new HQAudioExporter();
        };
    }
}

Client code

VideoExporter videoExporter = ExporterFactory.createVideoExporter(QUALITY_TYPE.HIGH);
AudioExporter audioExporter = ExporterFactory.createAudioExporter(QUALITY_TYPE.LOW);
videoExporter.exportVideo();
audioExporter.exportAudio();

In the above implementation, createVideoExporter and createAudioExporter are exposed to the client code. I think this is not an abstract factory design pattern, it is just a factory design pattern. To make it an Abstract factory pattern do I need to create another interface with the concrete implementations returning similar kinds of codecs like only HQAudioExporter and HQVideoExporter can be created from one implementation, and LQVideoExporter and LQAudioExporter from another implementation, Am I correct?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ enum QUALITY_TYPE should be enum QualityType to follow java-naming conventions \$\endgroup\$ Commented Jan 19, 2022 at 15:41

3 Answers 3

5
\$\begingroup\$

This code looks fine, it is indeed an implementation of a factory pattern.

However, why would both Audio and Video be in the same factory? Apart from having the same responsibility to export something, they probably won't have much in common.

You already have two interfaces, you should also have two factories.

\$\endgroup\$
2
\$\begingroup\$

The original code is not an implementation of the Abstract Factory Pattern. The Abstract Factory Pattern would look a bit different:

interface AbstractExporterFactory {
  VideoExporter createVideoExporter();
  AudioExporter createAudioExporter();
}

class HQExporterFactory implements AbstractExporterFactory {
    @Override
    public VideoExporter createVideoExporter(){
      return new HQVideoExporter();
    }
    @Override
    public AudioExporter createAudioExporter(){
      return new HQAudioExporter();
    }
}

class LQExporterFactory implements AbstractExporterFactory {
    @Override
    public VideoExporter createVideoExporter(){
      return new LQVideoExporter();
    }
    @Override
    public AudioExporter createAudioExporter(){
      return new LQAudioExporter();
    }
}

The client just need to know AudioExporter, VideoExporter and AbstractExporterFactory. Now for example UHQAudioExporter, UHQVideoExporter and corresponding UHQExporterFactory can be used without changes to the rest of the code. I personally would also replace Exporter by Player, which would make more sense for some real life application.

The client code looks more like an example how the pattern should not be used, as mixing HQ and LQ objects should be prevented.

\$\endgroup\$
0
1
\$\begingroup\$

Abstract Factory Pattern helps in correctly creating the families of related products. Using ExporterFactory, one could create a combination of LQVideoExporter and HQAudioExporter which I believe is unsupported. If it is valid then you could have use Builder pattern where HIGH and LOW are value types of Audio and Video exporters. Also, Factory objects are self sufficient and don't need any input to decide which type of products are to be created.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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