首页 > 编程语言 >Python: Factory Method Pattern

Python: Factory Method Pattern

时间:2022-10-06 13:44:27浏览次数:62  
标签:__ direction Python Pattern self move Factory pygame def

 

# Python 3.9
# 工厂方法模式 Factory Method Pattern

from __future__ import annotations
from abc import ABC, abstractmethod
import pygame  # pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple


class Shape(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def draw(self):
        raise NotImplementedError()

    def move(self, direction):
        if direction == 'up':
            self.y -= 4
        elif direction == 'down':
            self.y += 4
        elif direction == 'left':
            self.x -= 4
        elif direction == 'right':
            self.x += 4

    @staticmethod
    def factory(shape_type, pos_x, pos_y):
        if shape_type == 'Circle':
            return Circle(pos_x, pos_y)
        if shape_type == 'Square':
            return Square(pos_x, pos_y)
        assert 0, "Bad shape requested:" + type


class Square(Shape):
    def __init__(self, x, y):
        if x < 0:
            x = 0
        elif x > 780:
            x = 780
        if y < 0:
            y = 0
        elif y > 580:
            y = 580
        super(Square, self).__init__(x,y)

    def draw(self):
        pygame.draw.rect(
            screen,
            (255, 255, 0),
            pygame.Rect(self.x, self.y, 20, 20)
        )

    def move(self, direction):
        if direction == 'up' and self.y > 0:
            super(Square, self).move('up')
        elif direction == 'down' and self.y < 580:
            super(Square, self).move('down')
        elif direction == 'left' and self.x > 0:
            super(Square, self).move('left')
        elif direction == 'right' and self.x < 780:
            super(Square, self).move('right')


class Circle(Shape):
    def __init__(self, x, y):
        if x < 10:
            x = 10
        elif x > 790:
            x = 790
        if y < 10:
            y = 10
        elif y > 590:
            y = 590
        super(Circle, self).__init__(x, y)

    def draw(self):
        pygame.draw.circle(
            screen,
            (0, 255, 255),
            (self.x, self.y),
            10
        )

    def move(self, direction):
        if direction == 'up' and self.y > 10:
            super(Circle, self).move('up')
        elif direction == 'down' and self.y < 590:
            super(Circle, self).move('down')
        elif direction == 'left' and self.x > 10:
            super(Circle, self).move('left')
        elif direction == 'right' and self.x < 790:
            super(Circle, self).move('right')



class Creator(ABC):
    """
    The Creator class declares the factory method that is supposed to return an
    object of a Product class. The Creator's subclasses usually provide the
    implementation of this method.
    """

    @abstractmethod
    def factory_method(self):
        """
        Note that the Creator may also provide some default implementation of
        the factory method.
        """
        pass

    def some_operation(self) -> str:
        """
        Also note that, despite its name, the Creator's primary responsibility
        is not creating products. Usually, it contains some core business logic
        that relies on Product objects, returned by the factory method.
        Subclasses can indirectly change that business logic by overriding the
        factory method and returning a different type of product from it.
        """

        # Call the factory method to create a Product object.
        product = self.factory_method()

        # Now, use the product.
        result = f"Creator: The same creator's code has just worked with {product.operation()}"

        return result


"""
Concrete Creators override the factory method in order to change the resulting
product's type.
"""


class ConcreteCreator1(Creator):
    """
    Note that the signature of the method still uses the abstract product type,
    even though the concrete product is actually returned from the method. This
    way the Creator can stay independent of concrete product classes.
    """

    def factory_method(self) -> Product:
        return ConcreteProduct1()


class ConcreteCreator2(Creator):
    def factory_method(self) -> Product:
        return ConcreteProduct2()


class Product(ABC):
    """
    The Product interface declares the operations that all concrete products
    must implement.
    """

    @abstractmethod
    def operation(self) -> str:
        pass


"""
Concrete Products provide various implementations of the Product interface.
"""


class ConcreteProduct1(Product):
    def operation(self) -> str:
        return "{Result of the ConcreteProduct1}"


class ConcreteProduct2(Product):
    def operation(self) -> str:
        return "{Result of the ConcreteProduct2}"


def client_code(creator: Creator) -> None:
    """
    The client code works with an instance of a concrete creator, albeit through
    its base interface. As long as the client keeps working with the creator via
    the base interface, you can pass it any creator's subclass.
    """

    print(f"Client: I'm not aware of the creator's class, but it still works.\n"
          f"{creator.some_operation()}", end="")



def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.

  

 

调用:

# 调用 工厂方法模式 Factory Method Pattern
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('geovindu')
    window_dimensions = 800, 600


    print("App: Launched with the ConcreteCreator1.")
    client_code(ConcreteCreator1())
    print("\n")

    print("App: Launched with the ConcreteCreator2.")
    client_code(ConcreteCreator2())

    window_dimensions = 800, 600
    screen = pygame.display.set_mode(window_dimensions)

    obj = Shape.factory('Square', 100, 100)

    player_quits = False

    while not player_quits:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                player_quits = True

            pressed = pygame.key.get_pressed()
            if pressed[pygame.K_c]:
                obj = Shape.factory('Circle', obj.x, obj.y)
            if pressed[pygame.K_s]:
                obj = Shape.factory('Square', obj.x, obj.y)
            if pressed[pygame.K_UP]:
                obj.move('up')
            if pressed[pygame.K_DOWN]:
                obj.move('down')
            if pressed[pygame.K_LEFT]:
                obj.move('left')
            if pressed[pygame.K_RIGHT]:
                obj.move('right')

            screen.fill((0, 0, 0))
            obj.draw()
        pygame.display.flip()

 

输出:

 

 

Hi, geovindu
App: Launched with the ConcreteCreator1.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}

App: Launched with the ConcreteCreator2.
Client: I'm not aware of the creator's class, but it still works.
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}
Process finished with exit code 0

  

  

标签:__,direction,Python,Pattern,self,move,Factory,pygame,def
From: https://www.cnblogs.com/geovindu/p/16757473.html

相关文章

  • 利用摄像头拍照并保存照片的程序(python实现,含UI界面)
    摘要:许多情况下我们需要用到摄像头获取图像,进而处理图像,这篇博文介绍利用pyqt5、OpenCV实现用电脑上连接的摄像头拍照并保存照片。为了使用和后续开发方便,这里利用pyqt5......
  • python基础--基本概念
    1.脚本的文件格式  脚本名.py  eg:hello.py2.脚本结构  大概三部分,脚本头+导入部分+业务模块  每一块都是非必须的,按需填写即可;    为了书写规范,一般......
  • 功能 python
    1.获取变量类型a=1type(a)2.格式化字符串a=input()b="Iam{},andIamstudyingPythoninNowcoder!".format(a)print(b)3.控制小数的位置a=3.1415926b="{:.2f}".......
  • C++ 和 Python 的赋值操作 (等号“=“) 的区别
    C++和Python的赋值操作("=")的区别C++的赋值操作总是默认执行拷贝拷贝出来的副本与原来变量的地址不同除非是指针拷贝给指针的浅拷贝才会指向相同地址autoa=b;改变......
  • python 疫情监控系统
    ​随着新型冠状病毒肺炎(CoronaVirusDisease2019,COV⁃ID-19,简称“新冠肺炎”)的爆发,在当今世界格局愈发“地球村”的背景下,受疫情影响,对人们的正常生活和全球经济形成一......
  • 了解Python
    文章目录前言一、Python是什么?二、如何学习Python1.先学习其构架,再探究细节2.夯实基础,方有进阶之路三、结语 前言如何学习编写第一个程序,我相信每一......
  • python记录日志神器- loguru库
    写了这么多年的Python,我一直都是使用Python自带的logging模块来记录日志,每次需要写一些配置将日志输出到不同的位置,设置不同日志输出格式,或者将日志进行分文件和压缩......
  • Python基础(十一) | 超详细的Pandas库三万字总结
    ⭐本专栏旨在对Python的基础语法进行详解,精炼地总结语法中的重点,详解难点,面向零基础及入门的学习者,通过专栏的学习可以熟练掌握python编程,同时为后续的数据分析,机器学习及深......
  • python+selenium做ui自动化测试用法必会
    python+selenium做ui自动化测试用法必会一、前言大家都知道,基于Web端的测试的基础框架是需要Selenium做主要支撑的,这里边给大家介绍下Web测试核心之基于Python的Sele......
  • python一些函数库的安装
    python中如何安装libxml2?https://www.codenong.com/cs106853136/注意不是:pipinstalllibxml2而是pipinstalllxml 顺带了解其他python工具https://www.osgeo.cn/......