Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C, Delegate as Adapter Pattern: who is the adaptee?

I've read more than once that the Delegate Pattern used in Cocoa is an implementation of the Adaptern Pattern (http://en.wikipedia.org/wiki/Adapter_pattern). They share the same intent, which is: let two objects with incompatible interfaces to work with each other. The delegate object is the Adapter, because it adopts a protocol required by a client, the class that requires the protocol and has a weak reference to a delegate is the Client (so, this would be a class of the Cocoa framework). My question is: who is the Adaptee? The delegate pattern doesn't wrap itself around any object, from what I've seen, who is the object that needs to be adapted?

like image 703
AR89 Avatar asked Jan 10 '23 12:01

AR89


1 Answers

Delegates are not really an example of the Adapter pattern. Protocols would be closer, but the best way to implement the Adapter pattern in Objective C is to create a new object that contains the object you want to adapt and uses it to serve a client.

Categories are another way of implementing the Adapter pattern, but they have some limitations. You can't override the implementation of existing methods in a category, and you can't add additional instance variables to a class with a category. However you can implement properties using associated objects and you can also add new instance methods.

You can also use multiple inheritance to implement the Adapter pattern in languages like C++ that offer it, but Objective-C does not support multiple inheritance.

A simple example of an Adapter using a category that I use in my projects is as follows:

Interface Builder (IB) includes a feature called "User Defined Runtime Attributes" that lets you set properties on your custom interface objects using Key Value Coding (KVC). It lets you specify a limited number of data types (ints, floats, bools, points, rects, UIColors, and a few others.) You can use User Defined Runtime Attributes to set the border width and corner radius on a view's layer, and you SHOULD be able to use it to change the layer's border color or background color. However, layer colors are specified as CGColors, and UIViews use UIColors. Since IB only accepts UIColors in a User Defined Runtime Attribute, it doesn't work.

To fix this, I created a category of CALayer called CALayer+setUIColor. It has 2 methods, setBorderUIColor and setBackgroundUIColor. Those methods are very simple. They take UIColors as input, and simply convert the UIColor to a CGColor and set the layer's border color or background color.

You can see an early version of this category in my github project KeyframeViewAnimations.

like image 169
Duncan C Avatar answered Jan 22 '23 18:01

Duncan C