Lesson 1
Applying Factory and Adapter for Smart Home Devices
Applying Factory Method and Adapter Patterns for Smart Home Devices

This course is focused on integrating the design patterns we've studied into a practical project: building a smart home system. Throughout this course, you'll learn how to create and adapt various smart home devices using the Factory Method and Adapter patterns. By the end, you will have a solid understanding of how these design patterns can make your smart home system more efficient, modular, and easier to maintain.

In this unit, we explore two essential design patterns: Factory Method and Adapter. These patterns help us create and adapt devices within a smart home system. To effectively implement these patterns, we will build the devices using the Factory Method and then adapt these devices to interact with other parts of the system using the Adapter pattern.

Quick Summary
  1. Factory Method Pattern:

    • Purpose: Encapsulates the creation of objects, making it easier to introduce new object types without altering existing code.
    • Steps:
      • Define an abstract class (Device).
      • Create specific device classes (Light, Fan) inheriting from the abstract class.
      • Implement a factory class (DeviceFactory) to generate instances of these devices.
  2. Adapter Pattern:

    • Purpose: Makes incompatible interfaces compatible. Allows objects from different classes to work together.
    • Steps:
      • Define an adapter interface (USPlug).
      • Create adapter classes (LightAdapter, FanAdapter) that implement this interface and adapt the devices (Light, Fan) to the required interface.

Let’s move forward and start implementing these patterns.

Defining Smart Home Devices

Before diving into design patterns, we need to define the devices we'll be working with. Start by defining an abstract class Device and the concrete device classes Light and Fan that inherit from Device.

C#
1// Abstract Product 2abstract class Device 3{ 4 public abstract void TurnOn(); 5 public abstract void TurnOff(); 6} 7 8// Concrete Product - Light 9class Light : Device 10{ 11 public override void TurnOn() => Console.WriteLine("Light is on."); 12 13 public override void TurnOff() => Console.WriteLine("Light is off."); 14} 15 16// Concrete Product - Fan 17class Fan : Device 18{ 19 private int speed; 20 21 public override void TurnOn() => Console.WriteLine("Fan is on."); 22 23 public override void TurnOff() => Console.WriteLine("Fan is off."); 24 25 public void SetSpeed(int speed) 26 { 27 this.speed = speed; 28 Console.WriteLine("Fan speed set to " + speed + "."); 29 } 30}

With our basic devices defined, we can now integrate the Factory Method pattern.

Factory Method Pattern for Smart Home Devices

To begin with, we use the Factory Method pattern in C# to create an abstract class for our devices, derive specific device classes from this abstract class, and finally create a factory class responsible for generating instances of these device classes.

Let's break down the Factory Method pattern step by step.

Define Abstract Factory Class and Concrete Factory Classes

Define an abstract factory class DeviceFactory and the concrete factory classes LightFactory and FanFactory that create instances of Light and Fan.

C#
1// Abstract Creator 2abstract class DeviceFactory 3{ 4 public abstract Device CreateDevice(); 5} 6 7// Concrete Creator - LightFactory 8class LightFactory : DeviceFactory 9{ 10 public override Device CreateDevice() => new Light(); 11} 12 13// Concrete Creator - FanFactory 14class FanFactory : DeviceFactory 15{ 16 public override Device CreateDevice() => new Fan(); 17}
Integrate and Test Factory Method

Finally, integrate and test the Factory Method by creating instances of light and fan devices using the factory classes.

C#
1// Main Program 2class Program 3{ 4 static void Main() 5 { 6 // Create a Light using the LightFactory 7 DeviceFactory lightFactory = new LightFactory(); 8 Device light = lightFactory.CreateDevice(); 9 light.TurnOn(); // Output: Light is on. 10 light.TurnOff(); // Output: Light is off. 11 12 // Create a Fan using the FanFactory 13 DeviceFactory fanFactory = new FanFactory(); 14 Device fan = fanFactory.CreateDevice(); 15 fan.TurnOn(); // Output: Fan is on. 16 ((Fan)fan).SetSpeed(3); // Output: Fan speed set to 3. 17 fan.TurnOff(); // Output: Fan is off. 18 } 19}

In this implementation, DeviceFactory generates either a Light or a Fan device. The TurnOn and TurnOff methods are called on these devices to showcase their functionality.

Adapter Pattern for Smart Home Devices

Now, let's ensure our devices can interact with other parts of the system that expect a different interface. Specifically, we create an adapter to make our devices compatible with a method called Connect.

Let's also break down the Adapter pattern step by step.

Define Adapter Interface and Concrete Adapter Classes

First, define an interface USPlug and create adapter classes LightAdapter and FanAdapter that implement this interface to adapt the Light and Fan devices.

C#
1// Adapter Pattern for Smart Home Devices 2interface USPlug 3{ 4 void Connect(); 5} 6 7// Adapter for Light 8class LightAdapter : USPlug 9{ 10 private Device light; 11 12 public LightAdapter(Device light) 13 { 14 this.light = light; 15 } 16 17 public void Connect() => light.TurnOn(); 18} 19 20// Adapter for Fan 21class FanAdapter : USPlug 22{ 23 private Device fan; 24 25 public FanAdapter(Device fan) 26 { 27 this.fan = fan; 28 } 29 30 public void Connect() => fan.TurnOn(); 31}
Integrate and Test Adapter Pattern

Finally, integrate and test the Adapter pattern by creating devices using the factory and adapting them to the USPlug interface.

C#
1// Main Program 2class Program 3{ 4 static void Main() 5 { 6 // Create a Light device using the LightFactory 7 DeviceFactory lightFactory = new LightFactory(); 8 Device light = lightFactory.CreateDevice(); 9 // Adapt the Light to the USPlug interface 10 USPlug lightAdapter = new LightAdapter(light); 11 lightAdapter.Connect(); // Output: Light is on. 12 13 // Create a Fan device using the FanFactory 14 DeviceFactory fanFactory = new FanFactory(); 15 Device fan = fanFactory.CreateDevice(); 16 // Adapt the Fan to the USPlug interface 17 USPlug fanAdapter = new FanAdapter(fan); 18 fanAdapter.Connect(); // Output: Fan is on. 19 } 20}

In this implementation, we use the DeviceFactory to create instances of Light and Fan, then adapt these devices to the USPlug interface using the LightAdapter and FanAdapter classes. The Connect method is called on these adapters to showcase their functionality.

Conclusion

With these implementations, your smart home system will be more modular and flexible by using design patterns effectively. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.