I practiced design patterns so that I could write code that was conscious of design. Other Design Patterns will be released frequently.
The primary goal is to understand when, what, and how to use design patterns. (I'm new to Java or a statically typed language, and I don't have a long history of python, so I think there are some things that aren't like Pythonista. If you have any suggestions, please teach me.)
This time, the pattern Adapter related to the structure.
There are the following two types of Adapter patterns.
Create a conversion structure between the two classes and convert it so that it can be used for another purpose. Apdater is the role of the middle layer, and those who use it and those who use it do not need to know the contents. The point is the difference between returning as a class and returning as an instance.
Inheritance by class There is a sample program using the Apache pattern and a sample program by delegation. Both display the given string as (string) or \ * string \ *.
The Banner class has a method called show_with_paren that displays the character string in parentheses, and a method called show_with_paren that displays the character string with \ * marks before and after it. Suppose the Banner class is an existing one.
The Print interface declares a method print_weak to display a string weakly (in parentheses) and a method print_strong to display a string strongly.
The PrinterBanner class plays the role of an adapter. This class inherits from the provided Banner class and implements the required Printer interface. The PrinterBanner class now acts as an adapter.
banner.py
class Banner():
def __init__(self, string):
self.__string = string
def show_with_paren(self):
print('({0})').format(self.__string))
def show_with_aster(self):
print('({0})').format(self.__string))
printer.py
from abc import ABCMeta, abstractmethod
class Printer(metaclass=ABCMeta):
@abstractmethod
def print_weak(self):
pass
@abstractmethod
def print_strong(self):
pass
printer_banner.py
from banner import Banner
class PrinterBanner(Banner)
def __init__(self, string):
super().__init__(string)
def print_weak(self):
self.show_with_paren()
def print_strong(self):
self.show_with_aster()
The PrintBanner class acts as the Adapter.
Inherit the Banner class and inherit the show_with_paren and show_with_aster methods.
In addition, it implements the print_weak and print_strong methods with the required Printer interface.
main.py
from printer_banner import PrinterBanner
if __name__ == '__main__':
pb = PrinterBanner('Bye')
pb.print_weak()
pb.print_strong()
I am printing with print_weak () and print_strong () using the Printer interface. Since main does not know what kind of implementation the PrinterBanner class is, you can change the implementation of the PrinterBanner class without changing the main class.
In the sample program by delegation, Main and Banner have the same inheritance pattern. The only difference is the PrintBanner class. In other words, we will use the Banner class to realize a class that has the same methods as the Printer class.
The PrinterBanner class holds an instance of the Banner class in the banner field. This instance is created by the constructor of the PrinterBanner class. Then, in the print_weak and print_strong methods, the show_with_paren and show_with_aster methods are called via the banner field.
If you use inheritance, you will call the show_with_paren and show_with_aster methods inherited from your superclass, but in the delegation pattern you will call them via fields.
When the print_weak method of the PrinterBanner class is called, it is left to the show_with_paren method of another instance (Banner instance) instead of handling it by itself. This is a delegation.
printer_banner.py
from printer import Printer
from banner import Banner
class PrinterBanner(Printer):
def __init__(self, string):
self.__banner = Banner(string)
def print_weak(self):
self.banner.show_with_paren()
def print_strong(self):
self.banner.show_with_aster()
This time, it inherits the Printer class and first calls an instance of the Banner class.
The print_weak and print_strong methods are implemented using the show_with_paren and show_with_aster methods for the called instance.
Only the wording is changed, but the output result is the same.
inheritance/main.py
(Bye)
*Bye*
delegation/main.py
(Hello)
*Hello*
The Adapter pattern covers the existing class and creates the required class. In other words, the interface part is inserted in between to make up for the gap between the two different parties.
Even if there is a bug, we know that there are no bugs in the existing class, so we should focus on the class that plays the role of Adapter, which makes checking the program very easy, and that the existing class If you only know the specifications, you can create a new class.
Recommended Posts