Imagine you're developing a UI framework that supports multiple rendering technologies, such as DirectX and OpenGL. You want to separate the abstraction of UI components from their actual rendering implementations.
Implementor Interface:
// Implementor interface
public interface IRenderer
{
void RenderCircle(float radius);
}
Concrete Implementors:
// Concrete Implementor 1: DirectX renderer
public class DirectXRenderer : IRenderer
{
public void RenderCircle(float radius)
{
Console.WriteLine($"Rendering circle using DirectX with radius {radius}");
}
}
// Concrete Implementor 2: OpenGL renderer
public class OpenGLRenderer : IRenderer
{
public void RenderCircle(float radius)
{
Console.WriteLine($"Rendering circle using OpenGL with radius {radius}");
}
}
Abstraction:
// Abstraction
public abstract class Shape
{
protected IRenderer renderer;
protected Shape(IRenderer renderer)
{
this.renderer = renderer;
}
public abstract void Draw();
}
Refined Abstractions:
// Refined Abstraction 1: Circle shape
public class Circle : Shape
{
private float radius;
public Circle(float radius, IRenderer renderer) : base(renderer)
{
this.radius = radius;
}
public override void Draw()
{
renderer.RenderCircle(radius);
}
}
Client Code:
class Program
{
static void Main(string[] args)
{
// Create shapes with different renderers
Shape circle1 = new Circle(5f, new DirectXRenderer());
Shape circle2 = new Circle(10f, new OpenGLRenderer());
// Draw shapes
circle1.Draw();
circle2.Draw();
}
}