Talks

DCI != #extend && DCI != use case in code

This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!

wroc_love.rb 2013

00:00:18.160 My name is Rune Funch Søltoft. It's probably a bit easier for a Danish guy to translate that. I've promised to do a talk on DCI, and I've decided to call it 'DCI: Different from Extend', because every time I debate DCI with someone from the Ruby Community, they always say, 'Just extend'.
00:00:31.840 If you want to see examples of why that's not DCI, you could look at the Object Composition Group. I'm not going into that; I'm going to show a different way of doing it. I will focus on what DCI is.
00:00:55.960 But let's start out with who's talking. This is a picture of me when I wrote my first program, which was some years ago and written in Basic. Then, I got a bit older. This picture was taken around the time I started working on DCI. It has been a long way, and it's built on ideas that originate from the mid-60s when they built the first nuclear reactor in Norway.
00:01:23.880 I'm not that old, and this is me in my ordinary life, working as a consultant for a Polish company that was acquired a few years ago. If you want to know more about what I'm saying, pay attention to the blog up there or the Twitter handle. I blog about DCI and recently about using a small gem in Ruby.
00:01:57.119 To start out, what is object orientation? I'm in the Ruby community, and sometimes it feels like no one knows what object orientation is. We state and behavior should be the definition, okay? That sounds like Greg Young's normal thinking— I like that one.
00:02:10.319 Usually, if you go to places like Stack Overflow and ask about this question, you'll get responses about polymorphism, encapsulation, and some of their siblings. While it's true that those concepts are part of object orientation, they're also part of other paradigms. It's not what started object orientation, nor was it what object orientation was originally about. It's a way to model the user's mental model, preferably one-to-one.
00:02:34.319 This could be someone's mental model of their own living room. I'm not going to drop names, but I guess someone here understands what I'm talking about. So, what is DCI? It stands for Data, Context, and Interaction. And isn't it like—when you add functionality depending on where and in what context you use an object.
00:03:05.200 So, if I was in the living room, I would have certain things I could do. If I was somewhere else in the house, there would be other things I could do, but I would still be in a room, and you would still be you. That's definitely something you get with DCI.
00:03:51.680 The origins of DCI are the same as those of object orientation. Alan Kay coined the term 'object orientation', considering a computer system a network of interconnected systems where each object is also a system, and the definition is recursive.
00:04:03.280 In DCI, we're trying to represent this network of interconnected objects. It's also a paradigm. What's a paradigm? I'm a consultant, so I get to say words and just leave them hanging, but today we're going to dive a little deeper into what a paradigm truly is. It's a way to think, a concept—it's how you view things.
00:04:25.440 Object orientation is a paradigm, and functional programming is a paradigm as well. We can solve the same problems using both, but the way we think and structure our solutions is quite different.
00:04:48.199 Usually, when people talk about object orientation, they're more focused on class orientation rather than object orientation. You are a bit different; you're somewhere in between. You have classes, you construct objects, and you emphasize behavior, which is good.
00:05:03.800 So, has anyone tried using DCI in production code? Show of hands. A few have tried it for fun. Anyone attempted to sell it to their team at work and been unsuccessful? It's often because they said they had bigger problems to solve.
00:05:28.479 I've seen this main obstacle in Ruby several times: the argument that DCI is not fast enough. But to measure the speed of a paradigm is essentially challenging; it's akin to asking whether it's faster to drive or walk. It depends on how far you're going and what you're driving. It's a concept, a way of doing things, and it can indeed be fast.
00:06:03.880 In my view, DCI is a very intelligent way of designing systems. It fits well with the way I like to approach new systems, which is to start from the outside. I want to know who is going to use our application and what they actually need to accomplish.
00:07:04.759 Recently in Copenhagen, there was a case of fraud involving a company that tampered with meters, resulting in significantly inflated prices. This inspired me for an example. Our current system would like to enable users, on a website or mobile device, to verify the pricing of the fare based on two factors: the distance traveled and the duration of the journey.
00:07:23.680 If we translate that into code, we can start by defining key concepts. Can you see what's up there? It might be a bit hard to read, but I've laid out four key concepts: there's a route, a clock, and a price per unit. These represent how far we've traveled, the cost per meter, and the duration of the fare.
00:08:10.240 This is actually part of some running Ruby code using a gem called Maroon. It's an experimental gem but works adequately for our example. We start with these basic concepts, and I've set up a DCI context with three different roles: the route, the clock, and the pricing system. While we haven't yet defined the aspects of the pricing, we have solid conceptual groundwork.
00:09:05.680 We can present this setup in code and check with stakeholders if these concepts align with their expectations. Ideally, they would affirm that these indeed reflect our conceptual framework. The context we established represents the entire system logically, and we have roles assigned for the distance, time, and price per unit.
00:10:00.680 Next, there is a method we've implemented to calculate the fare, which utilizes the distance between two points as the route to determine pricing. However, as we've established, this is an overly simplistic model as pricing can vary based on numerous factors.
00:10:50.160 The initial system isn't adequate; we must account for variations like pricing strategies based on different locations and the increase in complexity for long-distance services. In theory, we began with a simple model, but we can identify areas where it becomes too basic, especially as we start to evolve the system. Remember, as we iterate our design, we maintain our foundational concept amidst the new developments.
00:12:10.079 DCI is a paradigm, not merely a pattern or a practice; it requires a shift in how you think about software design. Your goal is to reflect the user's needs in code, allowing for discussions around what the application should accomplish without getting bogged down by the technicalities of execution.
00:12:34.160 The performance of DCI depends on its implementation, not the paradigm itself. The gem I utilized in my examples executes as swiftly as any other standard method invocation does. There's no inherent complexity hindering performance; it's simply a matter of source transformation at play.
00:13:02.679 It should also be relatively easy to read, but I understand there's skepticism regarding DCI. Questions arise about whether the code using DCI is cleaner than other approaches. When comparing code structures, I can say that employing DCI can lead to cleaner organization.
00:13:52.200 After a recent lunch, I began an experiment with DCI and Maroon. I was amazed at how even in that brief time and with limited interaction, I was able to clarify the structure, leading to a more intelligible piece of code.
00:14:16.080 However, it's crucial to approach DCI with the correct mindset. My previous experiences led me to rely on outdated paradigms that complicated the clean implementation of DCI principles. Transitioning to DCI calls for a shift in thinking, and it's necessary to fully embrace it, using the correct tools.
00:14:50.400 Let me present you with a scenario. Suppose I am the President of the United States, and one evening, I want to switch roles and operate in a different capacity, handling personal matters like being a husband. In DCI, you can indeed change roles. However, roles exist only within a context, so they aren't persistent.
00:15:32.640 A critical distinction between DCI and traditional object-oriented programming is that in DCI, your role-based behavior doesn't persist outside its context. You can engage in multiple roles simultaneously, but as soon as you leave the context, that behavior fades.
00:15:47.840 The two primary motivations for creating the Maroon gem were: can we un-extend behavior, and can we play multiple roles simultaneously? Both answers are positive—it's feasible to take on several roles at once.
00:16:15.320 Diving into the difference between traditional approaches like functional programming and DCI can be enlightening. At its core, functional programming emphasizes the application of functions to data. However, DCI shifts focus to user interactions and system behaviors.
00:17:01.920 DCI involves a process that begins with understanding user needs rather than going straight into implementation. It's a form of design rooted in how people mentally interact with software rather than merely coding concepts.
00:17:27.560 In exploring the library to support DCI approaches, it's feasible to implement DCI strategies without a specific library such as Maroon. However, having a framework may simplify aspects of managing roles and interactions.
00:18:01.520 In Ruby, there have been several attempts to implement DCI, but the most successful implementations are typically those that do not rely on wrappers or injections, as those tend to complicate the conceptual model.
00:18:39.520 The context in DCI is responsible for binding roles to the respective players, ideally in an immutable fashion. This process enhances the ease of understanding code, as interactions are defined within that context.
00:19:12.520 It's crucial to ensure relationships are managed carefully, which influences how effectively systems can evolve as new functionalities are introduced. The concepts surrounding DCI tackle the complexity of operations while enhancing clarity and maintainability.
00:20:12.320 The roles in DCI are closely tied to their context and cannot be reused across different contexts. This distinction is significant as it helps prevent confusion that can arise from multiple variables sharing the same label.
00:20:45.440 Finally, the discussion leads back to the core philosophy behind DCI: it is about representing user interactions and system behavior according to user needs, keeping concepts organized and maintainable, ultimately creating a clearer path toward understanding and implementing solutions.
00:21:35.040 If you have more questions, feel free to reach out to me either now or after this session. Thank you.