<h2>Q1:您的实现是一个工厂吗</h2>
<p>工厂方法模式旨在</p>
<blockquote>
<p>define an interface for creating an object, but let the subclass
decide which class to instantiate - (<a href="https://en.wikipedia.org/wiki/Design_Patterns" rel="nofollow noreferrer">GoF</a>, page 107).</p>
</blockquote>
<p>您的设计和重新实现正是这样做的,并且是工厂</p>
<p><strong>更详细的参数</strong></p>
<p>在重新编写的解决方案中,根据图表,<code>PizzaStore</code>是某种上下文,可以使用<code>NYPizzaFactory</code>或<code>ChicagoPizzaFactory</code>或两者兼用。您的代码比UML更清晰,因为您在构建时将工厂注入到存储中</p>
<p>你们的工厂似乎都是生产产品实例的具体创造者。每个混凝土创造者都会制作一套不同的混凝土比萨饼。单独来看,您的每个<code>XxxPizzaFactory</code>似乎对应于一个混凝土工厂,该<code>FactoryMethod()</code>被称为<code>create_pizza()</code></p>
<p>图和代码中唯一缺少的是保证工厂是可互换的,允许它们从更一般的<code>PizzaFactory</code>继承。幸运的是,Python的动态类型可以处理缺少相同基类的情况。但出于维护目的,使用UML和Python更好地构造具有显式子类化的类</p>
<p><strong>工厂还是抽象工厂?</strong></p>
<p>每个具体工厂都可以创建不同类型的<code>Pizza</code>这一事实是被称为“<em><strong>参数化工厂方法</strong></em>”GoF的模式的变体,第110页)。因此,它确实是工厂模式,只是<code>create_pizza()</code>接受一个参数,该参数指定要实例化的具体比萨饼</p>
<p>这不是一个抽象工厂,因为抽象工厂旨在创建相关或从属产品的系列。家族中的每种产品都有其特定的工厂方法。如果您有几个create方法,比如<code>create_pizza(), create_dessert(), create_wine()</code>,那么这里就是这种情况。这里的情况并非如此,因为每个工厂只生产一种产品</p>
<h2>问题2:聚合还是依赖</h2>
<p>首先,GoF不使用UML(参见GoF,第363页)。本书撰写时,UML尚未正式出版:</p>
<ul>
<li>GoF对类图使用<a href="https://en.wikipedia.org/wiki/Object-modeling_technique" rel="nofollow noreferrer">OMT</a>而不是UML</li>
<li>GoF混合使用<a href="https://en.wikipedia.org/wiki/Booch_method" rel="nofollow noreferrer">Booch</a>和<a href="https://en.wikipedia.org/wiki/Object-oriented_software_engineering" rel="nofollow noreferrer">Objectory</a>作为交互图</李>
</ul>
<p>有趣的是,OMT、Booch和Objectory是三种主要的OO符号,它们被合并以创建UML</p>
<p>从UML的角度来看</p>
<ul>
<li><p><code>ConcreteCreator</code>和<code>ConcreteProduct</code>之间的关系是<a href="https://www.uml-diagrams.org/dependency.html#create" rel="nofollow noreferrer">^{<cd14>} dependency</a>。事实上,在<code>Creator</code>和<code>Product</code>之间也应该存在<code>«create»</code>依赖关系</p>
</li>
<li><p><code>Factory</code>和<code>Product</code>之间不应该有聚合,也不应该有关联(除非产品会跟踪创建它的工厂,或者工厂会保留它创建的所有产品的列表)</p>
</li>
<li><p>关于<a href="https://www.uml-diagrams.org/aggregation.html" rel="nofollow noreferrer">side of the agregation</a>有一个问题:您可以在<code>Client</code>和<code>Factory</code>之间使用聚合,但是在客户端使用菱形。尽管如此,虽然从根本上讲这并不是错误的,但是<a href="https://www.uml-diagrams.org/association.html" rel="nofollow noreferrer">simple association</a>更能代表这两个类之间的关系</p>
</li>
</ul>
<p>其他信息:</p>
<ul>
<li><a href="https://stackoverflow.com/a/62723620/3723423">Why a simple association would be more suitable than the aggregation in GoF</a>:这是对一个无关问题的回答的第二部分(在它的评论中,我列出了GoF中的incont用法,它在两个符号之间交替使用)</li>
<li><a href="https://stackoverflow.com/a/62562583/3723423">This answer</a>和<a href="https://stackoverflow.com/a/63401925/3723423">this answer</a>到不相关的问题解释了为什么在方法中创建、返回或临时使用类不足以创建关联(而且由于聚合比简单关联更强大,因此对于聚合来说更不够)</李>
</ul>
<p><em><strong>PS:</strong>我使用了<strong>GoF</strong>来指代“设计模式:可重用面向对象软件的元素”</em></p>