Do delegates defy OOP

I’m trying to understand OOP so I can write better OOP code and one thing which keeps coming up is this concept of a delegate (using .NET). I could have an object, which is totally self contained (encapsulated); it knows nothing of the outside world… but then I attach a delegate to it.

In my head, this is still quite well separated as the delegate only knows what to reference, but this by itself means it has to know about something else outside it’s world! That a method exists within another class!

Have I got myself it total muddle here, or is this a grey area, or is this actually down to interpretation (and if so, sorry as that will be off topic I’m sure). My question is, do delegates defy/muddy the OOP pattern?

3

In my head, this is still quite well separated as the delegate only knows what to reference, but this by itself means it has to know about something else outside it’s world!

But it doesn’t. Your delegate is just a variable that when invoked calls something. If you have a string variable, it could contain anything. Your class isn’t somehow breaking encapsulation if another class sets your string variable to “foobar”. Likewise, your class’ encapsulation is not broken if your delegate is set to “hide this UI widget when triggered”.

If OOP means each object is responsible for its own interface, then logically delegates could break OOP if it were not used properly. For example, if I made a FileStream class which, when asked to write, called a delegate to perform the write on behalf of the FileStream class, then it would breach OOP. This is because the responsibility of the write operation of the FileStream is purely upon FileStream if we’re following OOP to the letter.

However, this doesn’t mean that using delegates always goes against OOP. Using the same example, if I used a delegate to handle events before and after writes, this is still following OOP because it is not the responsibility of FileStream to know what should happen before and after writes. It should merely notify the classes which are responsible.

If passing delegates to an object were breaching OOP because it knows something outside its world, then also passing variables would breach OOP since you could think of delegates as passing code rather than data to classes. Acknowledging that there exists code outside of a single OOP class is not breaching anything.

No. Encapsulation doesn’t insist that an object “not know anything about the outside world.” It generally says two things:

  • Other objects don’t need to know how an objects does what it says it does.
  • All methods and attributes related only to serving a particular class are contained in that class.

The second point is often stated in various manners that can gives an impression that objects shouldn’t rely on outside stuff; but this is a highly impractical understanding, if not an impossible one. Consider a really basic class:

class Document {
  public String Title;
  public String Body;
}

Even without any further definition, our Document class already knows about “outside” things: It knows about Strings! (String is an externally defined class.) And, ignoring the potential XSS issues for a moment, we might make a method that looks like this:

public String GetHtmlBlurb() {
  return "<div><b>" + Title.Substring(0, 60) + "</b> "
    + body.Substring(0, 120) + "</div>";
}

The Substring method doesn’t exist in our Document definition either! It’s an externally defined method in the String class! But, this is perfectly expected, acceptable, generally necessary OO code. With the exception of classes built exclusively around primitives (do primitives really even exist in .NET?), a class is defined in terms of other classes (external stuff, the outside world, etc.).

Regarding delegates, we could have similarly defined our Document to work with a variety of Body types we have no other information about. All we might require is some way of producing a substring wherein there are multiple ways of doing so (perhaps one version adds elipses in certain cases). All our Document cares about is the ability to call some method that claims to be a Subtring-like method.

class Document {
  public String Title;
  public Func<Int32, Int32, String> BodySubstring;

  public String GetHtmlBlurb() {
    return "<div><b>" + Title.Substring(0, 60) + "</b> "
      + BodySubstring(0, 120) + "</div>";
  }
}

In brief: A delegate is just a reference to a method, rather than the full object we might otherwise include as a property. The difference is that our delegate doesn’t require the object to be of a certain type: only that a particular method have a certain signature. Our class doesn’t know what the object does and doesn’t insist on knowing anything about it. So, in that respect, it actually knows less about “the outside world.”

Perhaps it’s not an infringement on encapsulation. Perhaps it’s uberencapsulation.

1

A delegate is just another piece of data, an invokable bit of data, true, but still just data. It can be passed to another object, or exposed to and then changed by another object. Your object does not necessarily know about another object — your object could have the delegate set to a method inside itself.

You as the programmer know more, but the class doesn’t have to. Delegates make methods into data, and that is a good thing…

But what does it really know? By passing in a delegate, such as a callback, event handler, factory method, etc, all that is known by the code that gets this delegate reference is that it has a reference to something it can or should call at a specific time, or for a specific purpose. It doesn’t have to know exactly what that call will do (outside of any return value expected), where the actual code that will run lives, how it was chosen to be used as a delegate, etc. It needs no knowledge about this delegate other than it has it, and knows how to call it, which are the minimum requirements (in C# at least).

The delegate definition is therefore little more than a mini-interface; you define a delegate type, possibly named as to its ostensible purpose in consuming code, that expects a certain number of named parameters and is expected in turn to return a particular value. This is simplified even further with .NET 3.5’s built-in generic delegate types like Action, Func, Predicate, Comparison etc; you don’t even have to define your own strongly-typed delegate, just ask for a Func<string, string> (the downside being that general-purpose generics are, well, general-purpose and generic; you can’t use the delegate type name or parameter names to self-document what the delegate is expected to do for the calling code, or what types of things you should give it).

It’s similar, then, to a full interface definition, which defines a list of such methods, by name, with fully-defined signatures, all of which must be available in an implementing class. In Java, this is more or less how the same functionality you get with .NET delegates is achieved; an interface is defined with a single method representing the delegate method, classes exposing this method for use as a delegate are marked as implementing the interface, and a reference to the class is given, on which the method can be called. Delegates simply remove the middleman; you no longer care that the class containing the method implements any defined interface, you care that the actual method in question matches the required signature (here, signature is just parameter list and return type, not including method name). The class containing that method could then have a dozen methods with the same parameters and return type, but different names, and some machination your code doesn’t have to care about can choose a specific one to give to you as a delegate.

Understand that while C# is considered an object-oriented language, it is also a multi-paradigm language, incorporating procedural and functional aspects of other languages into itself on request or demonstrated need. Delegates were a lesson learned by observing Java programmers and their travails of setting up simple event-driven, multi-tier applications in a strictly-enforced object-oriented paradigm, requiring hundreds of highly specific single-method interfaces. Java eventually worked around this problem by allowing anonymous interface implementations, so code that needed to inject an interface could define a one-off implementation inline, but it can still be a bit verbose. The rumor mill is also churning that Oracle has given in to popular demand, and lambda statements and other delegates will be part of the upcoming Java 8 specification (along with a lot of other syntax sugar goodness that Java devs are salivating over after looking across the fence to the C# side).

C++ avoided that by retaining the highly pointer-based flexibility of the C lineage, but its limitation was that, unlike interfaces, function pointers couldn’t self-document; all you could know, without external documentation or traversing source code, is that you need to pass the address of a function, but you couldn’t know anything about what parameters the consumer would try to pass, what it might expect as a return value, what your function might be expected to do and when it might be called, etc. As the ability to write self-documenting code was a key tenet of C#’s language spec, the designers combined the two, by allowing function pointers in a sense, but requiring a strong definition of the method’s I/O signature as a type, allowing compiler-checked, self-describing function pointers without needing full interfaces.

1

No. Delegate complements OOP.

Because OOP has no notion of having function/method as data to be passed as event handler value, and for callbacks. Also having method as data therefore can be included as a parameter in the method, gaves us expressiveness and flexibility.

The necessity becomes more if you get introduced to code asynchronously, since you need to know which function/method as a callback to do something after your code returns continuations.

Therefore, please don’t limit yourself to the definition of OOP as is. Those established OOP languages such as C#, VB, F#, even C++ has supports for delegates, otherwise these languages will lose competitiveness if there are no delegate supports at all.

Of course if you’re implementing delegates in a bad way such as having bad smell in your code, the net result is the same as implementing OOP badly.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật