我有一些Python代码,它基于来自iCalendar文件的解析的VEvent对象创建一个Calendar对象.
日历对象只有一个方法,可以在解析时添加事件.
现在我想创建一个工厂函数,用于从文件对象,路径或URL创建日历.
我一直在使用iCalendar python模块,它直接在Class上实现工厂函数作为类方法,它返回一个实例:
cal = icalendar.Calendar.from_string(data)
从我对Java的了解很少,这是Java代码中的一种常见模式,尽管我似乎发现对工厂方法的更多引用与实际想要实例化实例的类不同.
问题是,这也被认为是Pythonic吗?或者只是创建一个模块级方法作为工厂函数,它被认为更pythonic?
[ 注意.将"日历"分为事件集合和"事件" - 日历上的单个事件时要非常谨慎.在你的问题中,似乎可能会有一些混乱.]
工厂设计模式有很多变化.
独立的便利功能(例如,calendarMaker(数据))
一个单独的类(例如,CalendarParser),用于构建目标类(Calendar).
类级方法(例如Calendar.from_string)方法.
这些有不同的目的.所有都是Pythonic,问题是"你是什么意思?" 和"什么可能改变?" 意义就是一切; 变化很重要.
便利功能是Pythonic.像Java这样的语言不能具有自由浮动功能; 你必须把一个孤独的功能包在课堂上.Python允许您拥有一个孤独的函数,而不需要类的开销.当构造函数没有状态更改或替代策略或以前操作的任何内存时,函数是相关的.
有时人们会定义一个类,然后提供一个方便函数,它创建类的实例,设置状态和策略的常用参数以及任何其他配置,然后调用类的单个相关方法.这为您提供了类的有状态以及独立功能的灵活性.
使用了类级方法模式,但它有局限性.一,它被迫依赖于类级变量.由于这些可能会造成混淆,因此当您需要添加功能(如有状态或替代策略)时,作为静态方法的复杂构造函数会遇到问题.确保您永远不会扩展静态方法.
二,它与其他类方法和属性或多或少无关.这种from_string
只是Calendar对象的许多替代编码之一.你可能有一个from_xml
,from_JSON
,from_YAML
和和.这些与日历是什么或它做什么没有最小的相关性.这些方法都是关于如何编码日历进行传输.
您将在成熟的Python库中看到的是工厂与它们创建的东西是分开的.编码(作为字符串,XML,JSON,YAML)受到大量或多或少的随机变化的影响.然而,重要的是很少改变.
将这两个问题分开.保持编码和表示尽可能远离状态和行为.
这是pythonic不考虑你在某处读到的某种模式中的深奥差异,现在想要在任何地方使用,比如工厂模式.
大多数时候你会想到@static方法作为解决方案,使用模块函数可能更好,除非你在一个模块中填充多个类,并且每个模块具有相同接口的不同实现,那么最好使用@静态方法
最终通过@static方法或模块函数创建实例的天气几乎没什么区别.
我可能会使用类的初始化程序(__init__),因为python中一个比较接受的"模式"是类的工厂是类初始化.