Home Backend Development PHP Tutorial The Layer Supertype Pattern: Encapsulating Common Implementation in Multi-Tiered Systems

The Layer Supertype Pattern: Encapsulating Common Implementation in Multi-Tiered Systems

Feb 26, 2025 am 11:51 AM

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();
}
Copy after login
<?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;
    }
}
Copy after login

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();
}
Copy after login
<?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;
    }
}
Copy after login

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>";
}
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

How to automatically set permissions of unixsocket after system restart? How to automatically set permissions of unixsocket after system restart? Mar 31, 2025 pm 11:54 PM

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

How to send a POST request containing JSON data using PHP's cURL library? How to send a POST request containing JSON data using PHP's cURL library? Apr 01, 2025 pm 03:12 PM

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

See all articles