Law of Demeter

Last updated

The Law of Demeter (LoD) or principle of least knowledge is a design guideline for developing software, particularly object-oriented programs. In its general form, the LoD is a specific case of loose coupling. The guideline was proposed by Ian Holland at Northeastern University towards the end of 1987, [1] and the following three recommendations serve as a succinct summary: [2]

Contents

  1. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
  2. Each unit should only talk to its friends; don't talk to strangers.
  3. Only talk to your immediate friends.

The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else (including its subcomponents), in accordance with the principle of "information hiding". It may be viewed as a corollary to the principle of least privilege, which dictates that a module possess only the information and resources necessary for its legitimate purpose.

It is so named for its origin in the Demeter Project, an adaptive programming and aspect-oriented programming effort. The project was named in honor of Demeter, “distribution-mother” and the Greek goddess of agriculture, to signify a bottom-up philosophy of programming which is also embodied in the law itself.[ citation needed ]

History

The law dates back to 1987 when it was first proposed by Ian Holland, who was working on the Demeter Project. This project was the birthplace of a lot of aspect-oriented programming (AOP) principles.

A quote in one of the remainders of the project seems to clarify the origins of the name: [3]

Demeter

The Greek goddess of Agriculture.

The Demeter project was named after Demeter because we were working on a hardware description language Zeus and we were looking for a tool to simplify the implementation of Zeus. We were looking for a tool name related to Zeus and we chose a sister of Zeus: Demeter.

We later promoted the idea that Demeter-style software development is about growing software as opposed to building software. We introduced the concept of a growth plan which is basically a sequence of more and more complex UML class diagrams.

Growth plans are useful for building systems incrementally.

In object-oriented programming

An object a can request a service (call a method) of an object instance b, but object a should not "reach through" object b to access yet another object, c, to request its services. Doing so would mean that object a implicitly requires greater knowledge of object b's internal structure.

Instead, b's interface should be modified if necessary so it can directly serve object a's request, propagating it to any relevant subcomponents. Alternatively, a might have a direct reference to object c and make the request directly to that. If the law is followed, only object b knows its own internal structure.

More formally, the Law of Demeter for functions requires that a method m of an object a may only invoke the methods of the following kinds of objects: [4]

In particular, an object should avoid invoking methods of an object returned by another method. For many modern object-oriented languages that use a dot as field identifier, the law can be stated simply as "use only one dot". [5] That is, the code a.m().n() breaks the law where a.m() does not. As an analogy, when one wants a dog to walk, one does not command the dog's legs to walk directly; instead, one commands the dog which then commands its own legs.

Advantages

The advantage of following the Law of Demeter is that the resulting software tends to be more maintainable and adaptable. Since objects are less dependent on the internal structure of other objects, object implementation can be changed without reworking their callers.

Basili et al. [6] published experimental results in 1996 suggesting that a lower Response For a Class (RFC, the number of methods potentially invoked in response to calling a method of that class) can reduce the probability of software bugs. Following the Law of Demeter can result in a lower RFC. However, the results also suggest that an increase in Weighted Methods per Class [7] (WMC, the number of methods defined in each class) can increase the probability of software bugs. Following the Law of Demeter can also result in a higher WMC.

A multilayered architecture can be considered to be a systematic mechanism for implementing the Law of Demeter in a software system. In a layered architecture, code within each layer can only make calls to code within the layer and code within the next layer down. "Layer skipping" would violate the layered architecture.

Disadvantages

Although the LoD increases the adaptiveness of a software system, it may result in having to write many wrapper methods to propagate calls to components; in some cases, this can add noticeable time and space overhead. [6] [8] [9]

At the method level, the LoD leads to narrow interfaces, giving access to only as much information as it needs to do its job, as each method needs to know about a small set of methods of closely related objects. [10] On the other hand, at the class level, if the LoD is not used correctly, wide (i.e., enlarged) interfaces may be developed that require introducing many auxiliary methods. [8] [9] This is due to poor design rather than a consequence of the LoD per se. If a wrapper method is being used, it means that the object being called through the wrapper should have been a dependency in the calling class.

One proposed solution to the problem of enlarged class interfaces is the aspect-oriented approach, [11] where the behavior of the method is specified as an aspect at a high level of abstraction. The wide interfaces are managed through a language that specifies implementations. Both the traversal strategy and the adaptive visitor use only a minimal set of classes that participate in the operation, and the information about the connections between these classes is abstracted out.

See also

Related Research Articles

<span class="mw-page-title-main">GNUstep</span> Open source widget toolkit and application development tools

GNUstep is a free software implementation of the Cocoa Objective-C frameworks, widget toolkit, and application development tools for Unix-like operating systems and Microsoft Windows. It is part of the GNU Project.

In software engineering and computer science, abstraction is the process of generalizing concrete details, such as attributes, away from the study of objects and systems to focus attention on details of greater importance. Abstraction is a fundamental concept in computer science and software engineering, especially within the object-oriented programming paradigm. Examples of this include:

The facade pattern is a software design pattern commonly used in object-oriented programming. Analogous to a façade in architecture, it is an object that serves as a front-facing interface masking more complex underlying or structural code. A facade can:

In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding behavior to existing code without modifying the code, instead separately specifying which code is modified via a "pointcut" specification, such as "log all function calls when the function's name begins with 'set'". This allows behaviors that are not central to the business logic to be added to a program without cluttering the code of core functions.

Software design is the process of conceptualizing how a software system will work before it is implemented or modified. Software design also refers to the direct result of the design process – the concepts of how the software will work which consists of both design documentation and undocumented concepts.

In computer science, separation of concerns is a design principle for separating a computer program into distinct sections. Each section addresses a separate concern, a set of information that affects the code of a computer program. A concern can be as general as "the details of the hardware for an application", or as specific as "the name of which class to instantiate". A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by encapsulating information inside a section of code that has a well-defined interface. Encapsulation is a means of information hiding. Layered designs in information systems are another embodiment of separation of concerns.

In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information. The exchange can be between software, computer hardware, peripheral devices, humans, and combinations of these. Some computer hardware devices, such as a touchscreen, can both send and receive data through the interface, while others such as a mouse or microphone may only provide an interface to send data to a given system.

Karl J. Lieberherr is a professor of Computer Science at Northeastern University, in Boston.

In computer programming, a software framework is an abstraction in which software, providing generic functionality, can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate the development of software applications, products and solutions.

Role-oriented programming as a form of computer programming aims at expressing things in terms that are analogous to human conceptual understanding of the world. This should make programs easier to understand and maintain.

A database abstraction layer is an application programming interface which unifies the communication between a computer application and databases such as SQL Server, IBM Db2, MySQL, PostgreSQL, Oracle or SQLite. Traditionally, all database vendors provide their own interface that is tailored to their products. It is up to the application programmer to implement code for the database interfaces that will be supported by the application. Database abstraction layers reduce the amount of work by providing a consistent API to the developer and hide the database specifics behind this interface as much as possible. There exist many abstraction layers with different interfaces in numerous programming languages. If an application has such a layer built in, it is called database-agnostic.

In object-oriented programming, inheritance is the mechanism of basing an object or class upon another object or class, retaining similar implementation. Also defined as deriving new classes from existing ones such as super class or base class and then forming them into a hierarchy of classes. In most class-based object-oriented languages like C++, an object created through inheritance, a "child object", acquires all the properties and behaviors of the "parent object", with the exception of: constructors, destructors, overloaded operators and friend functions of the base class. Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors, to reuse code and to independently extend original software via public classes and interfaces. The relationships of objects or classes through inheritance give rise to a directed acyclic graph.

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupled software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:

General Responsibility Assignment Software Patterns, abbreviated GRASP, is a set of "nine fundamental principles in object design and responsibility assignment" first published by Craig Larman in his 1997 book Applying UML and Patterns.

Naked objects is an architectural pattern used in software engineering. It is defined by three principles:

Domain-driven design (DDD) is a major software design approach, focusing on modeling software to match a domain according to input from that domain's experts.

Component Object Model (COM) is a binary-interface standard for software components introduced by Microsoft in 1993. It is used to enable inter-process communication (IPC) object creation in a large range of programming languages. COM is the basis for several other Microsoft technologies and frameworks, including OLE, OLE Automation, Browser Helper Object, ActiveX, COM+, DCOM, the Windows shell, DirectX, UMDF and Windows Runtime.

In computing, subject-oriented programming is an object-oriented software paradigm in which the state (fields) and behavior (methods) of objects are not seen as intrinsic to the objects themselves, but are provided by various subjective perceptions ("subjects") of the objects. The term and concepts were first published in September 1993 in a conference paper which was later recognized as being one of the three most influential papers to be presented at the conference between 1986 and 1996. As illustrated in that paper, an analogy is made with the contrast between the philosophical views of Plato and Kant with respect to the characteristics of "real" objects, but applied to software ones. For example, while we may all perceive a tree as having a measurable height, weight, leaf-mass, etc., from the point of view of a bird, a tree may also have measures of relative value for food or nesting purposes, or from the point of view of a tax-assessor, it may have a certain taxable value in a given year. Neither the bird's nor the tax-assessor's additional state information need be seen as intrinsic to the tree, but are added by the perceptions of the bird and tax-assessor, and from Kant's analysis, the same may be true even of characteristics we think of as intrinsic.

In the field of software engineering, the interface segregation principle (ISP) states that no code should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces. ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy. ISP is one of the five SOLID principles of object-oriented design, similar to the High Cohesion Principle of GRASP. Beyond object-oriented design, ISP is also a key principle in the design of distributed systems in general and microservices in particular. ISP is one of the six IDEALS principles for microservice design.

<span class="mw-page-title-main">Object-oriented programming</span> Programming paradigm based on the concept of objects

Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which can contain data and code: data in the form of fields, and code in the form of procedures. In OOP, computer programs are designed by making them out of objects that interact with one another.

References

  1. Lieberherr, K.J.; Holland, I.M. (September 1989). "Assuring good style for object-oriented programs". IEEE Software. 6 (5): 38–48. doi:10.1109/52.35588. ISSN   0740-7459. S2CID   12651917.
  2. Macedo, Emerson. "README.markdown: Demeter". GitHub. Retrieved 2012-07-05.
  3. "The Demeter Project - What is Demeter?".
  4. Bock, David. "The Paperboy, The Wallet, and The Law Of Demeter" (PDF). College of Computer and Information Science, Northeastern University. p. 5. Retrieved 2012-07-05.
  5. Metz, Sandi (2019). Practical Object-Ortiented Design: An Agile Primer Using Ruby (Second ed.). Addison-Wesley. p. 81. ISBN   0134456475. LCCN   2018939833.
  6. 1 2 Basili, Victor; Briand, L.; Melo, W. L. (October 1996). "A Validation of Object-Oriented Design Metrics as Quality Indicators" (PDF). IEEE Transactions on Software Engineering. 22 (10): 751–761. doi:10.1109/32.544352. hdl: 1903/715 . As expected, the larger the WMC, the larger the probability of fault detection.
  7. "Weighted Methods per Class - Maisqual Wiki". maisqual.squoring.com. Retrieved 2018-09-20.
  8. 1 2 Appleton, Brad. "Introducing Demeter and its Laws" . Retrieved 6 July 2013. A side-effect of this is that if you conform to LoD, while it may quite increase the maintainability and "adaptiveness" of your software system, you also end up having to write lots of little wrapper methods to propagate methods calls to its components (which can add noticeable time and space overhead).
  9. 1 2 "Tell, Don't Ask". The Pragmatic Programmers, LLC. Retrieved 6 July 2013. The disadvantage, of course, is that you end up writing many small wrapper methods that do very little but delegate container traversal and such. The cost tradeoff is between that inefficiency and higher class coupling.
  10. Lieberherr, K.; Holland, I.; Riel, A. (1988). "Object-Oriented Programming: An Objective Sense of Style" (PDF). In Meyrowitz, Norman (ed.). Conference proceedings on Object-oriented programming systems, languages and applications (OOPSLA '88). ACM. pp. 323–334. doi:10.1145/62083.62113. ISBN   978-0897912846. S2CID   562521 . Retrieved 2012-07-05. Easier software maintenance, less coupling between your methods, better information hiding, narrower interfaces, methods which are easier to reuse, and easier correct.ness proofs using structural induction.
  11. Lieberherr, Karl; Orleans, Doug; Ovlinger, Johan (October 2001). "Aspect-oriented programming with adaptive methods". Commun. ACM. 44 (10): 39–40. CiteSeerX   10.1.1.192.6403 . doi:10.1145/383845.383855. S2CID   2792493. An adaptive method encapsulates the behavior of an operation into one place, thus avoiding the scattering problem, but also abstracts over the class structure, thus avoiding the tangling problem as well.

Further reading