Adapter or Wrapper or Translator
Convert the interface of a class into another interface clients expect. An adapter lets classes work together that could not otherwise because of incompatible interfaces. The enterprise integration pattern equivalent is the Translator.
using System;
namespace DoFactory.GangOfFour.Adapter.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Adapter Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Target' class
/// </summary>
class Target
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
/// <summary>
/// The 'Adapter' class
/// </summary>
class Adapter : Target
{
private Adaptee _adaptee = new Adaptee();
public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
_adaptee.SpecificRequest();
}
}
/// <summary>
/// The 'Adaptee' class
/// </summary>
class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
Flyweight
Use sharing to support large numbers of similar objects efficiently.
Proxy
Provide a surrogate or placeholder for another object to control access to it.
interface Image {
void displayImage();
}
// on System A
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this .filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
System.out.println("Loading " + filename);
}
public void displayImage() {
System.out.println("Displaying " + filename);
}
}
//on System B
class ProxyImage implements Image {
private String filename;
private RealImage image;
public ProxyImage(String filename) {
this .filename = filename;
}
public void displayImage() {
If (image == null ) {
Image = new RealImage(filename);
}
image.displayImage();
}
}
class ProxyExample {
public static void main(String[] args) {
Image image1 = new ProxyImage("HiRes_10MB_Photo1");
Image image2 = new ProxyImage("HiRes_10MB_Photo2");
image1.displayImage(); // loading necessary
image1.displayImage(); // loading unnecessary
image2.displayImage(); // loading necessary
image2.displayImage(); // loading unnecessary
image1.displayImage(); // loading unnecessary
}
}
Inversion of Control
Everybody has probably seen (or written) code like this before:
public class EmailService
{
public void SendMessage() { ... }
}
public class NotificationSystem
{
private EmailService svc;
public NotificationSystem()
{
svc = new EmailService();
}
public void InterestingEventHappened()
{
svc.SendMessage();
}
}
Above NoticicationSystem has a dependency on EmailService.
The inversion of control (IoC) pattern is abstract; it says that one should move dependency creation out of the consumer class, but it doesn’t talk about exactly how to achieve that. In the following sections, we’ll explore two popular ways to apply the inversion of control pattern to achieve this responsibility shift: service locator and dependency injection.
public interface IMessagingService
{
void SendMessage();
}
public class EmailService : IMessagingService
{
public void SendMessage() { ... }
}
public class NotificationSystem
{
private IMessagingService svc;
public NotificationSystem()
{
svc = new EmailService();
}
public void InterestingEventHappened()
{
svc.SendMessage();
}
}
Design Pattern: Service Locator
Now if you re-write NotificationSystem in terms of the strongly-typed service locator, it might look like this:
Strongly typed service locator
public interface IServiceLocator
{
object GetService(Type serviceType);
TService GetService<TService>();
}
public static class ServiceLocatorExtensions
{
public static TService GetService<TService>(this IServiceLocator locator)
{
return (TService)locator.GetService(typeof(TService));
}
}
public class NotificationSystem
{
private IMessagingService svc;
public NotificationSystem(IServiceLocator locator)
{
svc = locator.GetService<IMessagingService>();
}
public void InterestingEventHappened()
{
svc.SendMessage();
}
}
Design Pattern: Dependency Injection
The dependency injection (DI) pattern is another form of the inversion of control pattern, where in there is no intermediary object like the service locator. Instead, components are written in a way that allows their dependencies to be stated explicitly, usually by way of constructor parameters or property setters. Constructor Injection
public class NotificationSystem
{
private IMessagingService svc;
public NotificationSystem(IMessagingService service)
{
this.svc = service;
}
public void InterestingEventHappened()
{
svc.SendMessage();
}
}
Property Injection
public class NotificationSystem
{
public IMessagingService MessagingService
{
get;
set;
}
public void InterestingEventHappened()
{
MessagingService.SendMessage();
}
}
Reads:
115
Pages:
176
Published:
Apr 2023
"No Filter, No Problem" by Famium is your ultimate guide to creating a visually stunning, engaging Instagram presence. Packed with insider secrets and practic...
Formats: PDF, Epub, Kindle, TXT