Hello everyone, today we are going to learn a new design mode called media Mode.

In fact, the so-called media is a kind of encapsulation idea, which abstracts the logic common to some functions into an intermediate medium, so as to reduce the coupling between codes, improve the extensibility, and make it more convenient for future demand changes.

A simple case

Let’s use a practical example to recognize the design pattern of media.

Let’s say we want to create a chat room. If we want to do it at all, it will be very complicated, involving a lot of network programming knowledge, such as broadcast, client, server, etc. We’ve simplified all of this for the sake of demonstration. At this extreme simplification, our chat room code is just a few lines:

class User:

    def __init__(self, name):

        self.name = name

       

    def say(self, message):

        call_something()

        print('[{} says:] {}'.format(self.name, message))

Copy the code

There’s not much to say about this logic, and I think you can understand it. Suppose we just fulfilled the product manager’s requirements, what would be the problem?

Functionally, of course, it was OK, but there were two big problems with the system design. The first is the logical repetition problem. We implemented the function of chatting in the chat room in the class User, the User object in the chat room. We will find that private conversations between users, videos between users, languages and so on May use the same logic, such as establishing network connections, such as sending messages, judging whether messages are sent successfully and so on.

But now the logic is written dead in the User class, if other classes want to use it, there is no reuse, only a copy of the code. Copying and copying makes the code very messy and difficult to maintain.

The second problem is the logical coupling problem. The User class is the User object class of the chat room, but it implements many of the functions of the chat room. This looks simple on the surface, but it’s really the code of two different concepts — chat room and user — coupled together. A lot of junk projects have this problem where I have to change the code in B when A is supposed to be A separate entity. Over time, even the developers themselves forget where they put the logic to implement something.

Through the analysis of this case, it is also the answer to the question why design patterns should be used. In most cases, design mode can not directly improve the operation efficiency of the project, its biggest function is to expand the code and maintainability. Without proper design patterns, as functionality increases, the project code becomes bloated until it becomes difficult for humans to maintain.

Media mode

So how can we use media design patterns to solve these two problems?

It’s actually quite simple, so let’s go straight to the code:

class ChatRoom:



    def display_message(self, user, message):

        print('[{} says]: {}'.format(user, message))





class User:



    def __init__(self, name):

        self.name = name

        self.chat_room = ChatRoom()



    def say(self, message):

        self.chat_room.display_message(self, message)

Copy the code

In other words, we abstracted the ChatRoom class from the User class and made it a member variable of the User class. The advantage of this is that we can avoid disturbing the User class when the chat room functionality needs to be reused or modified later. Otherwise, developers need to find the chatroom logic in the User class in a bunch of code and fix it, which, trust me, is not a great experience.

Of course, we’re not optimizing to the extreme here, and since there are so many instances of the User class, we find that every time we create an instance of the User class, we create an instance of the ChatRoom class, which is unnecessary and unnecessary. Therefore, we can design ChatRoom as a singleton mode, no matter how many instances the User creates, the same ChatRoom will be obtained, thus saving memory overhead.

Let’s rewrite the ChatRoom code using the singleton pattern:

import threading



class ChatRoom:

    _lock = threading.Lock()

    

    def __init__(self):

        pass

    

    

    def __new__(cls, *algs, **kw):

        if not hasattr(ChatRoom, '_instance') :

            with ChatRoom._lock:

                if not hasattr(ChatRoom, '_instance') :

                    ChatRoom._instance = object.__new__(cls)

  return ChatRoom._instance

Copy the code

At this point, the problem has been optimized to the limit. What seems to be a very simple function involves a lot of details and thinking, which is not as simple as it seems on the surface. These contents can not be learned from books, but can only be obtained through their own practice and thinking.

That’s all for today’s article. I sincerely wish you all a fruitful day. If you still like today’s content, please join us in a three-way support.

Link to the original article, click follow to get more articles