• Home
  • Tutorials
  • Development Tools
  • Contact Us

Developing Software

Mastering Software Craftsmanship

Abstract Factory Pattern: C# Example Using the Unity Game Engine

10th October 2016 by @developingsoft

Abstract Factory: Provide an interface for creating families of related or dependent objects without specifying their concrete classes. – Design Patterns: Elements of Reusable Object-Oriented Software

The quote above is from the the Gang of Four book and describes the intent of the Abstract Factory design pattern.

The original book goes into a lot more detail about how you can use the pattern but for this post I will try to explain it in simple terms using the Unity game engine.

What is the Abstract Factory?

Let’s assume we have a scenario where we want to display adverts in our game. Our game runs on Android and iOS but there is no existing advertising API built into the Unity game engine. We have discovered a native solution called AdMob but it requires us to write some separate code to call the native plugin on each platform.

This is a potential use case for the Abstract Factory because we can detect what platform the game is running on at the start and then use the Abstract Factory to create the family of components required to display advertisements for that platform.

An Example Using Unity

The following image shows a class diagram of how we can use the Abstract Factory pattern to create our advertising API.

Abstract Factory Class Diagram

In the next steps we will create some basic interfaces and classes that match the design from the class diagram. I will not go into detail about the structure of the Unity project because you can check it out on GitHub.

AbstractAdvertFactory

The AbstractAdvertFactory class in an abstract class that defines the abstract methods CreateBannerAdvert() and CreateVideoAdvert(), returning an IBannerAdvert and IVideoAdvert object respectively.

public abstract class AbstractAdvertFactory
{
    public abstract IBannerAdvert CreateBannerAdvert();
    public abstract IVideoAdvert CreateVideoAdvert();
}

iOSAdvertFactory

The concrete subclass iOSAdvertFactory returns the objects specific to the iOS platform.

public class iOSAdvertFactory : AbstractAdvertFactory
{
    public override IBannerAdvert CreateBannerAdvert()
    {
        return new iOSBannerAdvert();
    }

    public override IVideoAdvert CreateVideoAdvert()
    {
        return new iOSVideoAdvert();
    }
}

AndroidAdvertFactory

The concrete subclass AndroidAdvertFactory returns the objects specific to the Android platform.

public class AndroidAdvertFactory : AbstractAdvertFactory
{
    public override IBannerAdvert CreateBannerAdvert()
    {
        return new AndroidBannerAdvert();
    }

    public override IVideoAdvert CreateVideoAdvert()
    {
        return new AndroidVideoAdvert();
    }
}

If we needed to port our game to another platform we could create a new subclass for that platform. For example WindowsAdvertFactory.

Using the Abstract Factory

The client program will instantiate the appropriate factory using some code like the following.

public class Client : MonoBehaviour
{
    public string _whatToMake = "iOS";

    private AbstractAdvertFactory _advertFactory;

    // Use this for initialization
    void Start()
    {
        switch (_whatToMake)
        {
            case "iOS":
                _advertFactory = new iOSAdvertFactory();
                break;
            case "Android":
                _advertFactory = new AndroidAdvertFactory();
                break;
            default:
                throw new Exception("Unable to find advert factory implementation");
        }

        var bannerAdvert = _advertFactory.CreateBannerAdvert();
        Debug.Log(bannerAdvert);
        bannerAdvert.Show();
        bannerAdvert.Hide();

        var videoAdvert = _advertFactory.CreateVideoAdvert();
        Debug.Log(videoAdvert);
        videoAdvert.Play();
        videoAdvert.Stop();
    }
}

Attaching this script to a Unity game object will create the iOSAdvertFactory at runtime. This is because of the iOS string in the _whatToMake field. Changing value to Android will create the AndroidAdvertFactory.

This is just an example and I’m sure you could come up with better ways of detecting what platform is in use. You could even combine this with the Singleton creation pattern to make a single entry point to creating the Factory and only ever creating it once.

Concrete Family Objects

One thing you will notice is I have missed out the interface declarations and implementation details for the returned family objects. You can see more details in AbstractFactory folder of the GitHub project.

All you need to know is that your platform specific calls into native code would go in the returned concrete objects. For example AndroidBannerAdvert and iOSBannerAdvert.

Conclusion

The good thing about the Abstract Factory pattern is that our client code has an identical set of method calls for each family object.

Just make sure you plan your design well in advance because the pattern can become a pain when you need to add new family objects. The reason for this is because you need to amend each existing factory class and create new family objects.

Further Reading

More detailed discussion on the Gang of Four design patterns can be found in the following publications:

  • Gamma, E. et al. 1994. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
  • Freeman, E. et al. 2004. Head First Design Patterns. O’Reilly Media.
  • Bevis, T. 2012. C# Design Pattern Essentials. AbilityFirst.
Share this on:

Filed Under: Tutorials Tagged With: C#, Design Patterns, Gang of Four, Unity

Search

Advertisement

Newsletter

Subscribe now to receive practical tips on how to become a better software developer.

Free - No Spam - 100% Email Privacy

Featured Posts

Abstract Factory Pattern: C# Example Using the Unity Game Engine

23 Software Design Patterns That Will Make You a More Effective Programmer

How to Deploy an ASP.NET Core Website to Ubuntu with Git

How to Run an ASP.NET Core Website in Production on Ubuntu Linux

How to Install the Edimax Wireless nano USB Adapter on Windows IoT Core for Raspberry Pi

How to Convert a Post Title into a Friendly URL (Slug) in C#

How to Convert Markdown to HTML in ASP.NET Core

How to Send an E-Mail with ASP.NET Core and Mailgun

How to Generate a Sitemap in ASP.NET MVC and ASP.NET Core

How to Create an MD5 Hash of a String in C# and Displaying a Gravatar Image

© 2014–2023 Developing SoftwareTerms • Privacy