Design Pattern - Structural Patterns - Adapter Pattern

50 篇文章 0 订阅
37 篇文章 0 订阅

2007

Section 1, Chapter 4


Adapter Pattern


Concept

It creates an adaptation between two classes of different types so they can become interchangeable. In other words, the adapter allows the target to perform normally on the outside but inside it will actually use the adaptee's methods and functionality.


Use

It is useful when dealing with incompatible class types in a class solution where it is desired that neither class have any real association directly with the other, but that they use similar methods.


Design

The Adapter pattern has three important components: the Target, Adapter, and Adaptee.

  • The target is the class for which we wish to implement the adapter. We inherit from the target to create our adapter.
  • The adapter is the class that provides the join for the two disparate class types and houses the methods for conjoining functionality between them. It is an inherited member from the target.
  • The adaptee is the class that we wish to give access to the methods and functionality of the target.




Illustration



class Element
{
	.....
	public virtual void SetVaporTemperature(float temperature)
	{
		.....
	}
	public virtual void SetFreezeTemperature(float temperature)
	{
		.....
	}
	public virtual void SetNormalTemperature(float temperature)
	{
		.....
	}
}


//Adaptee
class Water
{
	public void SetBoilingTemperature(float temperature)
	{
		.....
	}
	public void SetIceTemperature(float temperature)
	{
		.....
	}
	public void SetLiquidTemperature(float temperature)
	{
		.....
	}
}


//Adapter
class WaterAdapter : Element
{
	private Water _adaptee = new Water();
	public WaterAdapter(string typeName) : base (typeName){}
	public override void SetVaporTemperature(float temperature)
	{
		_adaptee.SetBoilingTemperature(temperature);
	}
	public override void SetFreezeTemperature(float temperature)
	{
		_adaptee.SetIceTemperature(temperature);
	}
	public override void SetNormalTemperature(float temperature)
	{
		_adaptee.SetLiquidTemperature(temperature);
	}
}



Note: The author keeps saying the target and adaptee are interchangeable, but they are not in fact. You won't say a child class and its base class are interchangeable.




December 2007

Section 1, Chapter 4



Design

The Client works to a domain-specific standard, which is specified in the ITarget interface. An Adaptee class provides the required functionality, but with a different interface. The Adapter implements the ITarget interface and routes calls from the Client through to the Adaptee, making whatever changes to parameters and return types are necessary to meet the requirements.

A Target class that implements the ITarget interface directly could exist, but this is not a necessary part of the pattern. In any case, the Client is aware only of the ITarget interface, and it relies on that for its correct operation.


Two ways to implement this pattern:

  • Class adapter: a adapter class implements ITarget interface, and inherits Adaptee class. With this way, overriding Adaptee  behavior can be done more easily.
  • Object adapter: aggregating the Adaptee class, by creating an object of it on . With this way, adding behavior to Adaptees can be done more easily.




The adapter shown in the figure is a class adapter.


using System;
// Adapter Pattern - Simple Judith Bishop Oct 2007
// Simplest adapter using interfaces and inheritance
// Existing way requests are implemented
class Adaptee {
	// Provide full precision
	public double SpecificRequest(double a, double b) {
		return a/b;
	}
}

// Required standard for requests
interface ITarget {
	// Rough estimate required
	string Request(int i);
}

// Implementing the required standard via Adaptee
class Adapter : Adaptee, ITarget {
	public string Request(int i) {
		return "Rough estimate is " + (int) Math.Round(SpecificRequest(i, 3));
	}
}

class Client {

	static void Main() {
		// Showing the Adapteee in standalone mode
		Adaptee first = new Adaptee();
		Console.Write("Before the new standard\nPrecise reading: ");
		Console.WriteLine(first.SpecificRequest(5,3));

		// What the client really wants
		ITarget second = new Adapter();
		Console.WriteLine("\nMoving to the new standard");
		Console.WriteLine(second.Request(5));
	}
}


A feature of adapters is that they can insert additional behavior between the ITarget interface and the Adaptee. They do not have to be invisible to the Client.

We have the following options when matching adapter and adaptee interfaces:

  • Adapter interface and adaptee interface have same signature
  • Adapter interface has fewer parameters than adaptee interface
  • Adapter interface has more parameters than adaptee interface
  • Adapter interface has other types than adaptee interface


Two-Way Adapters



Pluggable Adapters



2016
Chapter 8





class Rect
{
	public double l;
	public double w;
}

class Triangle
{
	public double b;	//base
	public double h;	//height
	public Triangle(int b, int h)
	{
		this.b = b;
		this.h = h;
	}
}

class Calculator
{ 
	Rect rectangle;
	public double getArea(Rect r)
	{
		rectangle=r;
		return rectangle.l * rectangle.w;
	}
}

class CalculatorAdapter
{
	Calculator calculator;
	Triangle triangle;
	public double getArea(Triangle t)
	{
		calculator = new Calculator();
		triangle=t;
		Rect r = new Rect();
		//Area of Triangle=0.5*base*height
		r.l = triangle.b;
		r.w = 0.5*triangle.h;
		return calculator.getArea(r);
	}
}

public class AdapterPattern
{
	public static void main(String[] args)
	{
		System.out.println("***Adapter Pattern Demo***");
		CalculatorAdapter cal=new CalculatorAdapter();
		Triangle t = new Triangle(20,10);
		System.out.println("\nAdapter Pattern Example\n");
		System.out.println("Area of Triangle is :" + cal.getArea(t));
	}
}



Discussion about two different types of the pattern, object adapter and object adapter.




Let's convert the names of the classes in second case to the terms in adapter pattern context.




Both cases demonstrated in this book, are not strictly conforming the definition of adapter pattern. In this pattern, one important thing is there is no direct relationship between the Target and the Adaptee, and that's why we need an adapter in between. However, in the first case, there is no entity playing the role as Target, you could say at most the CalculatorAdapter class is a wrapper of Calculator, as there is no fore-established protocol about the interface.
And the second case, there is direct relationship between the Target and the Adaptees, which nullifies the meaning of the adapter classes. According to the code, it's just normal implementation,there is no pattern in it at all.





Vincent's Demonstration


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值