
type
//target interface
IEuroSocket = interface
function GetPower: string;
end;
//existing class with a wrong interface
TUsSocket = class
public
function GetUsPower: string;
end;
//class adapter: inherits the adaptee
//and implements the target
TSocketAdapter = class(TUsSocket,
IEuroSocket)
private
FRefCount: Integer;
public
function GetPower: string;
function QueryInterface(const IID: TGUID;
out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
function TUsSocket.GetUsPower: string;
begin
Result := '110V';
end;
function TSocketAdapter.GetPower: string;
begin
Result := GetUsPower + ' as 220V';
end;
function TSocketAdapter.QueryInterface(
const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TSocketAdapter._AddRef: Integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TSocketAdapter._Release: Integer;
begin
Dec(FRefCount);
Result := FRefCount;
end;
var
Socket: IEuroSocket;
begin
Socket := TSocketAdapter.Create;
WriteLn(Socket.GetPower);
//110V as 220V
end.
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.Read moreThe problem. Your program reads text from any source through one method. A ready library class keeps lines of text and can join them, but through a method with another name. You cannot change the library. You also do not want to change all the code that calls the method it expects. The idea. An adapter makes an existing class, the adaptee, fit the interface that the client expects, the target. In this version the adapter is a subclass of the adaptee and also implements the target. Its target method only calls the inherited method, sometimes with a small conversion. So the adapter is itself an adaptee and keeps all its methods. Compare the adapter by composition: it holds an adaptee instead of extending it. How to read the example. The adaptee already does the work, but under another method. The target declares the method that the client expects. The adapter extends the adaptee and adds the target method, which calls the inherited one. There is only one object: the adapter is the adaptee. In most languages the client fills it through the adaptee's own methods and reads the result through the target method. Languages without class inheritance imitate it: they embed the adaptee, or they add the target method to the adaptee's own type. When to use it. Use a class adapter when you adapt one known class and also need its other methods. Do not use it when the object to adapt already exists, or when it may belong to a subclass of the adaptee. A class adapter is always a new object of one fixed class, so it cannot adapt such objects. A common mistake. Forgetting that the adapter shows every method of the adaptee. Clients start to call these methods directly, and the target no longer hides the adaptee. |