python编写脚本方法
If you’ve ever read Design Patterns before, you may have learned about a classic pattern called the “Factory Method”. This pattern makes a base class more flexible by allowing its children to specify what objects to create. Rather than having object names be hard-coded into the parent class they are deferred to the children. This pattern makes extending the class easier and ensures more loosely coupled objects.
如果您以前曾经阅读过设计模式 ,那么您可能已经了解了一种称为“工厂方法”的经典模式。 通过允许子类指定要创建的对象,此模式使基类更加灵活。 不是将对象名称硬编码到父类中,而是将它们推迟给子代。 这种模式使扩展类变得更加容易,并确保了对象之间的松散耦合。
For example, let’s say you have a parent Bicycle
class. You want every Bicycle
to have a set of tires (I would hope). So, every time a new Bicycle
is initialized you automatically assign the tires
to GenericTires
. Seems okay right? But what about when you want a different type of Bicycle
with a different type of tires
? What if the GenericTires
interface changes or you want to swap it out completely? You have to update the parent Bicycle
class. Having to comb through code and update hard-coded elements like this is tedious, inflexible and error prone.
例如,假设您有一个Bicycle
父课程。 您希望每辆Bicycle
都有一套轮胎(我希望如此)。 因此,每次初始化新的Bicycle
,您都会自动将tires
分配给GenericTires
。 看起来还好吧? 但是,当您想要使用不同类型tires
的不同类型Bicycle
时又如何呢? 如果GenericTires
接口发生更改,或者您想将其完全换出怎么办? 您必须更新父Bicycle
类。 像这样必须梳理代码并更新硬编码的元素是单调乏味,不灵活且容易出错的。
The goal using the Factory Method is to make objects more extensible and abstract so they are easier to use. The rule of thumb is:
使用工厂方法的目的是使对象更具可扩展性和抽象性,从而使它们更易于使用。 经验法则是:
“Create objects in a separate operation so that subclasses can override the way they’re created.” — Design Patterns (1994)
“在单独的操作中创建对象,以便子类可以覆盖其创建方式。” - 设计模式(1994)
This is precisely what we’ll explore how to do in Python.
这正是我们将探索如何在Python中进行操作的内容。
初步设计 (The Initial Design)
In this first example we’ll go over what a piece of code commonly looks like where the Factory Method can be applied. We’ll use our handy Bicycle
example because who doesn’t love going for a nice bike ride. I also find it easier to grasp concepts like this when the classes model physical things we’re familiar with. Sandi Metz also frequently uses building a bicycle in example code and I’m a huge fan of the analogy. Let’s dive in.
在第一个示例中,我们将介绍可以应用工厂方法的一段代码。 我们将使用方便的“ Bicycle
示例,因为谁不喜欢骑自行车出行。 当类对我们熟悉的物理事物进行建模时,我还发现更容易掌握这样的概念。 桑迪·梅斯(Sandi Metz)还经常在示例代码中使用构建自行车,我非常喜欢这种类比。 让我们潜入。
class Bicycle:
def __init__(self):
self.tires = GenericTires() def get_tire_type(self):
return self.tires.tire_type()class GenericTires:
def tire_type(self):
return 'generic'bike = Bicycle()
print(bike.get_tire_type())
In this example the parent class Bicycle
initializes with a set of GenericTires
by referring to the class directly. This makes the coupling between Bicycle
and GenericTires
more tight and rigid. Creating different types of bicycles is possible but changing their tires is not intuitive in this example.
在此示例中,父类Bicycle
通过直接引用该类而使用一组GenericTires
进行初始化。 这使Bicycle
和GenericTires
之间的连接更加紧密和牢固。 可以创建不同类型的自行车,但在此示例中更换轮胎并不直观。
Let’s say we want to build a new kind of bike. A mountain bike. It should probably have some special tires to handle the rough terrain, right? How can we adjust the base Bicycle
class to be more flexible for different kinds of tires?
假设我们要制造一种新型的自行车。 一辆山地自行车。 它可能应该有一些特殊的轮胎来应对崎terrain的地形,对吗? 我们如何调整基本的Bicycle
类以适应不同类型的轮胎?
Here is a slightly more flexible design:
这是一个稍微更灵活的设计:
class Bicycle:
def __init__(self):
self.tires = self.add_tires() def add_tires(self):
return GenericTires() def get_tire_type(self):
return self.tires.tire_type()class MountainBike(Bicycle):
def add_tires(self):
return MountainTires()class GenericTires:
def tire_type(self):
return 'generic'class MountainTires:
def tire_type(self):
return 'mountain'mountain_bike = MountainBike()
print(mountain_bike.get_tire_type())
In this example we’ve added a new add_tires()
method for returning the proper tire class. This lets us override that method in any of the subclasses of Bicycle
and provide a different class of tires. In order to add a new bike and tire you only need to add the new classes and override the method. You don’t have to make adjustments to the base class. Next, let’s look at extending this even further for when you have more complex bike parts.
在此示例中,我们添加了新的add_tires()
方法以返回正确的轮胎类。 这使我们可以在Bicycle
任何子类中覆盖该方法,并提供不同类别的轮胎。 为了添加新的自行车和轮胎,您只需要添加新的类并覆盖该方法。 您不必对基类进行调整。 接下来,让我们看看当您拥有更复杂的自行车零件时,可以进一步扩展它。
更灵活的设计 (A More Flexible Design)
Here we showcase a more flexible and “client friendly” design similar to the Abstract Factory pattern. This example adds a factory
parameter to the parent class which will accept a kind of “part factory” for specifying the type of tires or other parts to create.
在这里,我们展示了一种类似于抽象工厂模式的更加灵活和“客户友好”的设计。 此示例将factory
参数添加到父类,该参数将接受一种“零件工厂”,用于指定要创建的轮胎或其他零件的类型。
class Bicycle:
def __init__(self, factory):
self.tires = factory().add_tires()
self.frame = factory().add_frame()class GenericFactory:
def add_tires(self):
return GenericTires() def add_frame(self):
return GenericFrame()class MountainFactory:
def add_tires(self):
return RuggedTires() def add_frame(self):
return SturdyFrame()class RoadFactory:
def add_tires(self):
return RoadTires() def add_frame(self):
return LightFrame()class GenericTires:
def part_type(self):
return 'generic_tires'class RuggedTires:
def part_type(self):
return 'rugged_tires'class RoadTires:
def part_type(self):
return 'road_tires'class GenericFrame:
def part_type(self):
return 'generic_frame'class SturdyFrame:
def part_type(self):
return 'sturdy_frame'class LightFrame:
def part_type(self):
return 'light_frame'bike = Bicycle(GenericFactory)
print(bike.tires.part_type())
print(bike.frame.part_type())mountain_bike = Bicycle(MountainFactory)
print(mountain_bike.tires.part_type())
print(mountain_bike.frame.part_type())road_bike = Bicycle(RoadFactory)
print(road_bike.tires.part_type())
print(road_bike.frame.part_type())
We no longer specify the type of parts to install in the parent class at all. Adding parts is handled by each respective add_tires()
and add_frame()
method inside the part factory. The part factory is simply a separate class that handles adding each concrete part. The parent Bicycle
class calls the methods to add parts within the part factory class. Each instance is still a Bicycle
but built with different parts.
我们完全不再指定要在父类中安装的部件的类型。 零件工厂中零件的添加方法分别由add_tires()
和add_frame()
方法处理。 零件工厂只是一个单独的类,用于处理每个具体零件的添加。 父Bicycle
类调用在零件工厂类中添加零件的方法。 每个实例仍然是一辆Bicycle
但具有不同的零件。
There are also some additional steps you could take to abstract the previous set of classes even further:
您还可以采取一些其他步骤来进一步抽象先前的类集:
Generalize
add_tires()
andadd_frame()
toadd_part('type')
将
add_tires()
和add_frame()
add_part('type')
为add_part('type')
Create a method in the parent
Bicycle
class for displaying all parts associated with the bike. You could accomplish this by simply getting eachpart_type()
or movingself.tires
andself.frame
into a list or map of parts to iterate over.在父类
Bicycle
类中创建一个方法,用于显示与自行车关联的所有零件。 您可以通过简单地获取每个part_type()
或将self.tires
和self.frame
移动到零件列表或零件图中以进行迭代来完成此操作。Right now
Bicycle
expects a part factory to be passed in. You could include theGenericFactory
inside the class as default assignments that can be overridden by new factories.现在,
Bicycle
希望传递一个零件工厂。您可以将GenericFactory
作为默认分配包含在类中,新工厂可以覆盖该默认分配。
These examples are only some of the ways to write and extend Factory patterns in Python. There are a number of other variations. Which one you choose depends entirely on the size of the project and complexity of the class. In some cases, maybe you just need to override one method in the parent, in others you’ll need a dedicated factory class to instantiate multiple objects. Ultimately, whichever option you choose should feel natural and provide a simple, extensible interface for clients.
这些示例只是在Python中编写和扩展Factory模式的一些方法。 还有许多其他变体。 您选择哪一个完全取决于项目的规模和课程的复杂性。 在某些情况下,也许您只需要在父级中重写一个方法,在其他情况下,您将需要专用的工厂类来实例化多个对象。 最终,无论您选择哪种选择,都应该感觉自然,并为客户提供一个简单,可扩展的界面。
Thanks for reading! Hopefully you’ve enjoyed learning about how the Factory Method design pattern works in Python. If you wan’t more fun Python guides, check out 5 Python String Methods For Better Formatting.
谢谢阅读! 希望您喜欢在Python中学习Factory Method设计模式的工作方式。 如果您不需要更多有趣的Python指南,请查看 5种Python字符串方法以获得更好的格式 。
翻译自: https://levelup.gitconnected.com/writing-a-simple-factory-method-in-python-6e48145d03a
python编写脚本方法