


The Layer Supertype Pattern: Encapsulating Common Implementation in Multi-Tiered Systems
Core points
- Layer supertype mode is crucial in multi-layer systems, and it can encapsulate common implementations in different classes, thereby facilitating code reuse and reducing duplication.
- Implementing the layer supertype pattern involves creating a shared base class that abstracts public logic and properties and then extends by a more specific subclass.
- This mode helps maintain a clearer code architecture, as it allows for the modification of shared functionality in one place, thereby enhancing maintainability and scalability.
- The layer hypertype pattern not only simplifies the code base, but also aligns well with the single responsibility principle because it separates public behavior from class-specific behavior.
- While this pattern provides many benefits in reducing boilerplate code and redundant code, it must be applied with caution to avoid creating overly complex or large superclass structures that can be difficult to manage.
Inheritance, as one of the cornerstones of object-oriented programming, is like a double-edged sword. It can not only bring powerful code reuse mechanisms, avoid the complexity brought by using combination patterns, but also lead to a chaotic inheritance system. , the behaviors of subtypes and base types are so different that the "IS-A" relationship is in name only. Although there are many pitfalls in inheritance, most of them can be mitigated by rational and moderate use. Code reuse is the root cause of inheritance. Inheritance can play a huge role when adding boilerplate implementations to multi-layer system abstractions. Inheritance provides an easy way to easily generate large numbers of semantically interrelated objects without duplicating code. Its concept is very simple but powerful: first put as much logic as possible within the boundaries of the base type (usually abstract classes, but also concrete classes), and then start deriveing refined subtypes according to more specific needs. This process is usually performed on a "per-layer" basis, thereby providing each layer with its own set of supertypes, whose core functions are refined and extended in turn by the corresponding subtypes. Not surprisingly, this duplicate encapsulation/derived loop follows a design pattern called "layer supertype" (yes, it does have a real academic name, though a bit naive), in the next few lines , I'll dig into how it works internally, and you'll be able to see how easy it is to connect its functionality to the domain model.
Level super type requirements—Defining bloated domain model
It can be said that layer supertypes are the natural and selective evolution of the "common" base type, except that the latter exists within the scope of a specific layer. This plays an important role in multi-layer design where utilizing super-type functions is often a necessary requirement, not just arbitrary decision. In general, the most effective way to understand the practicality behind this pattern is through some practical examples. So, suppose we need to build a simple domain model from scratch, responsible for defining some basic interactions between some blog posts and their corresponding comments. Roughly speaking, the model can be easily outlined as a layer of anemia, containing only a few skeleton classes for modeling articles and comments. The first domain class and its contract may look like this:
<?php namespace Model; interface PostInterface { public function setId($id); public function getId(); public function setTitle($title); public function getTitle(); public function setContent($content); public function getContent(); public function setComment(CommentInterface $comment); public function setComments(array $comments); public function getComments(); }
<?php namespace Model; class Post implements PostInterface { protected $id; protected $title; protected $content; protected $comments = array(); public function __construct($title, $content, array $comments = array()) { $this->setTitle($title); $this->setContent($content); if (!empty($comments)) { $this->setComments($comments); } } public function setId($id) { if ($this->id !== null) { throw new BadMethodCallException( "The ID for this post has been set already."); } if (!is_int($id) || $id throw new InvalidArgumentException( "The post ID is invalid."); } $this->id = $id; return $this; } public function getId() { return $this->id; } public function setTitle($title) { if (!is_string($title) || strlen($title) || strlen($title) > 100) { throw new InvalidArgumentException( "The post title is invalid."); } $this->title = htmlspecialchars(trim($title), ENT_QUOTES); return $this; } public function getTitle() { return $this->title; } public function setContent($content) { if (!is_string($content) || strlen($content) throw new InvalidArgumentException( "The post content is invalid."); } $this->content = htmlspecialchars(trim($content), ENT_QUOTES); return $this; } public function getContent() { return $this->content; } public function setComment(CommentInterface $comment) { $this->comments[] = $comment; return $this; } public function setComments(array $comments) { foreach ($comments as $comment) { $this->setComment($comment); } return $this; } public function getComments() { return $this->comments; } }
The driver of the Post class is simple logic, which boils down to defining the data and behavior of some basic post entries. It should be easy to understand. Now let's make the model a little fatter by adding a class to it that generates comments associated with a specific blog entry. Its contract and implementation are as follows:
<?php namespace Model; interface CommentInterface { public function setId($id); public function getId(); public function setContent($content); public function getContent(); public function setAuthor($author); public function getAuthor(); }
<?php namespace Model; class Comment implements CommentInterface { protected $id; protected $content; protected $author; public function __construct($content, $author) { $this->setContent($content); $this->setAuthor($author); } public function setId($id) { if ($this->id !== null) { throw new BadMethodCallException( "The ID for this comment has been set already."); } if (!is_int($id) || $id throw new InvalidArgumentException( "The comment ID is invalid."); } $this->id = $id; return $this; } public function getId() { return $this->id; } public function setContent($content) { if (!is_string($content) || strlen($content) throw new InvalidArgumentException( "The content of the comment is invalid."); } $this->content = htmlspecialchars(trim($content), ENT_QUOTES); return $this; } public function getContent() { return $this->content; } public function setAuthor($author) { if (!is_string($author) || strlen($author) throw new InvalidArgumentException( "The author is invalid."); } $this->author = $author; return $this; } public function getAuthor() { return $this->author; } }
Like Post, the Comment class is simple. But now with these two classes, we can use the model. For example:
<?php use LibraryLoaderAutoloader, ModelPost, ModelComment; require_once __DIR__ . "/Library/Loader/Autoloader.php"; $autoloader = new Autoloader; $autoloader->register(); $post = new Post( "A sample post.", "This is the content of the post." ); $post->setComments(array( new Comment( "One banal comment for the previous post.", "A fictional commenter"), new Comment( "Yet another banal comment for the previous post.", "A fictional commenter") )); echo $post->getTitle() . " " . $post->getContent() . "<br></br>"; foreach ($post->getComments() as $comment) { echo $comment->getContent() . " " . $comment->getAuthor() . "<br></br>"; }
This is indeed as effective as charm! Using this model is a fairly simple process that requires you to first create some Post objects and then populate them with relevant comments. Yes, life is sweet and beautiful. OK, so far, but it can certainly be better! I'm not trying to destroy the magic of such a wonderful moment, but I have to admit that I feel a slight chill every time I see the implementation of Post and Comment classes. While this is not a serious problem in itself, some methods (such as setId() and setContent()) show typical symptoms of code duplication. Due to some logical problems, solving this problem without carelessness is not as intuitive as it may seem at first glance. First, although they have semantic relationships with each other, each class actually models different types of objects. Second, they implement different interfaces, which means it is difficult to abstract the logic without ending up with a clumsy hierarchy where the "IS-A" condition never holds true. Especially in this case, we can take a more relaxed approach and treat Post and Comment as subtypes of the highly general AbstractEntity supertype. In doing so, placing a shared implementation within the boundaries of an abstract class would be very simple, thus making the definition of subtypes more streamlined. Since the entire abstraction process only takes place at the domain layer, the hypothetical AbstractEntity will be treated as...Yes, you guessed it, a layer supertype. Simple but good, right?
(The remaining code and explanation are omitted here due to space limitations. Note that the code examples in the original text are long, and translating and generalizing all codes will make the answer too verbose. The core idea is to create AbstractEntity
Class to extract duplicate code in the Post
and Comment
classes, thereby reducing code redundancy and improving maintainability. )
Summary
Although inheritance is often considered a mechanism for overestimation and abuse, I hope very few people will disagree now that inheritance is a powerful mechanism that works when used neatly in a multi-layer system prevents duplication of code. Using a simple pattern like layer supertype is an example of the many fascinating advantages that inheritance provides when creating subtypes that share a large number of boilerplate implementations with each other.
(The FAQ part of the original text is also omitted here because its content is a repetition and extension of the core ideas of the article. Translating all the content will make the answer too long. The core ideas have been fully reflected in the above translation.)
The above is the detailed content of The Layer Supertype Pattern: Encapsulating Common Implementation in Multi-Tiered Systems. For more information, please follow other related articles on the PHP Chinese website!

PHP remains a powerful and widely used tool in modern programming, especially in the field of web development. 1) PHP is easy to use and seamlessly integrated with databases, and is the first choice for many developers. 2) It supports dynamic content generation and object-oriented programming, suitable for quickly creating and maintaining websites. 3) PHP's performance can be improved by caching and optimizing database queries, and its extensive community and rich ecosystem make it still important in today's technology stack.

In PHP, weak references are implemented through the WeakReference class and will not prevent the garbage collector from reclaiming objects. Weak references are suitable for scenarios such as caching systems and event listeners. It should be noted that it cannot guarantee the survival of objects and that garbage collection may be delayed.

The \_\_invoke method allows objects to be called like functions. 1. Define the \_\_invoke method so that the object can be called. 2. When using the $obj(...) syntax, PHP will execute the \_\_invoke method. 3. Suitable for scenarios such as logging and calculator, improving code flexibility and readability.

Fibers was introduced in PHP8.1, improving concurrent processing capabilities. 1) Fibers is a lightweight concurrency model similar to coroutines. 2) They allow developers to manually control the execution flow of tasks and are suitable for handling I/O-intensive tasks. 3) Using Fibers can write more efficient and responsive code.

The PHP community provides rich resources and support to help developers grow. 1) Resources include official documentation, tutorials, blogs and open source projects such as Laravel and Symfony. 2) Support can be obtained through StackOverflow, Reddit and Slack channels. 3) Development trends can be learned by following RFC. 4) Integration into the community can be achieved through active participation, contribution to code and learning sharing.

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP is not dying, but constantly adapting and evolving. 1) PHP has undergone multiple version iterations since 1994 to adapt to new technology trends. 2) It is currently widely used in e-commerce, content management systems and other fields. 3) PHP8 introduces JIT compiler and other functions to improve performance and modernization. 4) Use OPcache and follow PSR-12 standards to optimize performance and code quality.

The future of PHP will be achieved by adapting to new technology trends and introducing innovative features: 1) Adapting to cloud computing, containerization and microservice architectures, supporting Docker and Kubernetes; 2) introducing JIT compilers and enumeration types to improve performance and data processing efficiency; 3) Continuously optimize performance and promote best practices.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 Linux new version
SublimeText3 Linux latest version

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Atom editor mac version download
The most popular open source editor