在主题中使用OOP


36

我看到很多插件在不需要时都使用了面向对象的编码。

但是更糟糕的是主题开发人员开始做同样的事情。商业主题和免费流行主题,例如Suffusion,甚至是我最喜欢的主题-Hybrid,都将其所有功能填充在一个类中,然后在functions.php中实例化一次,并以程序方式运行它的功能:)

WTF?这样做有什么意义?显然,您不会同时使用两个或多个相同主题的实例。

假设插件为名称空间执行此操作(这很荒谬),但是主题借口是什么?我想念什么吗?

编写这样的主题有什么好处?


5
@Ambitious Amoeba-您能解释一下为什么您认为对插件使用类以最小化名称空间冲突是荒谬的吗?至于主题,如果您可以举例说明您认为主题中的好代码是什么以及您认为不必要的代码,那么这可能也会有所帮助。对您或其他人,尤其是对您所指的内容不熟悉的其他人,以抽象方式讨论此问题可能不会获得任何见识。
MikeSchinkel 2010年

1
我可以在任何个人可以使用的地方使用类,对我来说,维护,更新和重用要容易得多。除了个人喜好,使用课堂有什么好的理由?
t31os 2010年

1
奇怪,只是失去了我的原始注释(也许是SE错误?)。尽管我会重复一遍,但有什么好的理由使用课程呢?
t31os 2010年

2
@MikeSchinkel:您可以通过在函数名称后添加前缀来实现。我认为仅拥有漂亮的函数名就不值得额外的类开销。无论如何,我很好奇为什么主题会这样做,而不是插件那么多
onetrickpony 2010年

4
@雄心勃勃的变形虫-我当然会同意你有权发表自己的意见,但我的意见有所不同。我认为,通过最小化全局命名空间中浮动的函数将类带给代码的清晰度值得我认为是有效的,不可估量的额外开销,尤其是当使用像PhpStorm这样的专业级IDE时。类创建一个独立的单元,以便开发人员可以知道模块需要什么代码。最后,在将我的WordPress插件样式演变为使用类之后,其他任何方法对我来说都像是草率的编码。
MikeSchinkel 2010年

Answers:


26

根据您提供的示例,我可以理解您的困惑。这实际上是使用类的一种糟糕方法……并且仅仅因为使用了类,并不会使系统成为OOP。

对于Hybrid,他们只是使用一个类来命名其函数的名称。考虑到Hybrid是一个主题框架,这样做是为了使子主题可以重用函数名称,而开发人员不必担心名称冲突。在许多情况下,主题框架(父主题)是如此复杂,许多子主题开发人员将永远无法确切了解幕后情况。

如果Hybrid不使用类结构,则子主题开发人员将需要知道所有现有函数调用是什么,以便避免重复使用名称。是的,您可以在所有函数的前面加上一个独特的代码,但这会使代码难以阅读,难以维护,并且如果您要开发更多希望使用相同功能的系统,则代码固有地不可重用。

回答您的问题

WTF?这样做有什么意义?显然,您不会同时使用两个或多个相同主题的实例。

不,您不会使用同一主题的两个或更多实例。但是就像我说的,在这种情况下,将类结构视为对函数进行命名,而不是创建传统的对象实例。将所有内容集中在一个类中,然后将其实例化为调用方法(myClass->method();)或直接调用方法(myClass::method();),这是一种以可读,可重用的方式命名事物的非常干净的方法。

当然,您总是可以使用类似的代码myClass_method();,但是如果您想在另一个主题,插件或其他框架中重复使用任何这些代码,则必须重新检查并更改所有前缀。将所有内容保持在课堂上会更干净,并使您可以更快地进行重新开发和重新部署。

假设插件为名称空间执行此操作(这很荒谬),但是主题借口是什么?我想念什么吗?

在大多数情况下,我会同意你的看法。但是,大多数人正在迅速减少。我在MultiSite安装中托管了几个使用同一主题的变体的站点。我有一个单一的“父类”主题,而不是一遍又一遍地重新创建相同的主题,而所有子主题都扩展了该类。这使我可以为每个站点定义自定义功能,同时仍保持整个网络的总体一致性。

一方面,主题开发人员可以选择基于类的方法来命名其功能的名称空间(如果您在一个环境中反复使用相同代码的块的环境中工作,这并不荒谬)。另一方面,主题开发人员可以选择基于类的方法,以方便按子主题进行扩展。

编写这样的主题有什么好处?

如果您仅在网站上使用Hybrid,那么作为最终用户的优势就不多了。如果您要为Hybrid构建子主题,则命名空间和可扩展性会带来很多好处。如果您为ThemeHybrid工作,则优势在于可以在其他项目(Prototype,Leviathan等)中快速,高效地重用代码。

而且,如果您是主题开发人员,并且喜欢混合功能的特定功能,但不喜欢整个主题,那么优势在于您可以在非混合项目中快速,高效地重用代码(假设它也是GPL)。


我不同意“可扩展性”部分。与使用动作和典型功能时一样,您对父主题具有相同级别的控制。为什么?您自己说过的,这不是真正的OOP。我也不同意命名空间-这就是为什么我从第一个地方开始这个问题-尝试从任何插件中的Hybrid重新定义任何函数,您会发现这些函数会发生冲突。您为什么认为他们仍然添加了前缀?:)您只是不能将整个主题包装在一个类中,这根本没有任何意义……
onetrickpony 2010年

相反,我并不是说不要在主题中使用OOP,就像一些人可能理解的相反(例如,请参阅2.8小部件,例如walker等),但不是这样。
onetrickpony 2010年

1
似乎您对Hybrid的特定实现有问题,而不是在主题中使用OOP甚至使用类对主题中定义的函数进行命名的做法都没有问题。我正试图回答您更广泛的问题:为什么?然后重新:这样做的好处是什么?我不会花任何时间来捍卫似乎是一心二意的实现,也不会争论您对特定主题框架结构的明显敌意。最重要的是,如果您不喜欢Hybrid的构建方式,请使用其他方法。
EAMann

1
一点也不,我喜欢混合动力车(当然不喜欢上课)。Hybrid促使我创建自己的主题框架。再举一个例子,Suffusion,相同类型的练习。同样,在这种情况下,名称空间不适用于主题,包装类中的所有功能将始终与插件冲突,因为插件是通过WP“主题”加载的。
onetrickpony 2010年

1
很公平。只是要记住,大多数WP工作并不是以OOP开头(因为WP不是),但是将主题方法放在类中以模仿其在插件中的工作方式至少是正确的一步。方向...即使这是一个构思不完善且执行不佳的课程。我绝对同意,仅将所有内容包装在一个类中并以过程方式进行调用是有点奇怪的(对于尝试使用该系统的第三方开发人员的POV而言,它没有用)。但是,如果做得正确(在Hybrid中显然不是),则对代码进行分类functions.php可能会非常强大。
EAMann 2010年

29

速度

我当前的基本主题有13个课程。构建新主题时,可以按原样使用这些类,也可以扩展它们。该系统使建立新主题的过程非常非常快。

狭窄的范围

我很少需要全局变量,因为我的代码必须知道的所有内容都隐藏在类成员中。因此,我能够在两个截然不同的过滤器或操作之间共享变量,而不会与编写不良的插件发生冲突。

保养

每个类是一个文件。如果我需要更新客户的主题,则只需更新一些文件即可。只要我提供相同的API,类中发生的一切都取决于我。

一个例子:在comment_form();调用上方,我使用一个简单的操作:

do_action( 'load_comment_class' );
comment_form();

将加载哪个注释类决定了我的控制器。究竟发生了评论类的内部决定个人类。

用纯粹的程序方法尝试一下,您会发疯。:)

可读性

如果您已按其任务将所有内容分开,那么几个月后重新阅读和理解自己的代码将变得非常容易。

有用的类层次结构的一些示例

  • Meta_Box- >通过扩展Shortdesc_Meta_BoxSimple_Checkbox_Meta_Box- >通过延长Sidebar_Switch
  • User_Profile_Addon->扩展User_Profile_Checkbox(请参阅问题3255
  • Comment_Form ->扩展 {$theme_name}_Comment_Form

1
有机会参加“主题”课程吗?我想写我自己的,我想知道你是怎么做到的。
Horttcore 2010年

1
我还没有决定。也许明年我将与@bueltge一起认识一个新的基本主题,其中使用了其中一些课程。恐怕很可能不在游行之前。
fuxia

5
特别是对于您的案例,免费主题和框架,OOP是必经之路。其他人必须使用这些代码。作者应使此过程尽可能简单和灵活。替换类比替换20个函数更容易,因为编写良好的类具有明确定义的API。
fuxia

2
关于混合动力车我什么也不能说。我从来没有用过。但是,是的,一个可以组织所有幕后工作,提供良好过滤器并将一些 MVC模式插入到常见主题混乱中的控制器–是一件好事。不要相信我 试试吧。:)
fuxia

3
现在是时候了,WordPress需要面向开发人员的OOP主题。我希望我们有时间为我们的目标而努力。这里的摘录和好处表明,以客户主题为目标的可能性很大。快速实现新主题的方法也对维护非常有用。
bueltge'1

3

要考虑的另一点:速度。

if ( !class_exists('cccYourClassName') )  
// VERSUS  
if ( !function_exists('ccc_your_function_name') )

简短查看/打印后,我发现〜1.700内部功能和〜1.400用户功能=〜3.100 / 3.200功能VS。约250个班级。我想这最能说明查询多少。如果您需要!function_exists('')在主题中调用约50-100个函数,只需为它设置一个计时器,然后开始做一些数学运算即可。即使不是OOP,这也是编写代码的好方法

1)可重复使用
2)可维护
3)可交换
4)快一点

当您查看网络中浮动的各种类以帮助您快速完成元框,小部件等时,最好使用提到的@toscho这样的控制器,因为您可以将类插入和插入,然后替换控制器中处理您的类的某些行。


2

一些人认为封装是OOP提供的唯一(或至少是主要的)好处,并且继承和状态介于无聊与邪恶之间:

http://obiecte.blogspot.com/2008/09/oop-sucks.html

作者谈论的更多是关于使用类/对象作为结构,而不是将其用作静态函数的容器,但是有趣的是,从一个完全不在OOP阵营之外的人那里读到了一个截然不同的问题。

我可能会在Haskell中编写我的下一个WordPress插件。


1
不幸的是,博客仅向“受邀”用户开放。另一个提醒我们为什么我们永远不要在免费服务上发布我们的信息,而应该托管我们自己的博客。Facebook在这方面几乎相同。更新的资源链接会很好。FWIW我已经看到了OOP的阴暗面,除非在上下文中是绝对必要的,否则它将永远不会再次使用它,因为高阶函数通常可以扩展功能并有助于减少样板和class关键字的误用。
乔什·哈布达斯

2

噢,真是个讨论!我还必须承认,我经常使用类进行封装。这里的想法是,在我的插件中,我可以将函数包装在一个类中,并且在该类中使用非常简单,有意义的方法名称,这些名称即使在我编写的其他插件中也是通用的。在那种情况下,类是名称空间的替代,我不得不在5.2.x环境中避免使用。

虽然很少有OOP对模块化有用的情况,但是包装函数的简单动作也带来了跨插件可扩展性的额外好处。例如,我最近扩展了一个基于类的发票解决方案,这样我就可以扩展主类,向各种函数(带有parent :: calls)添加额外的代码,甚至替换函数,而所有这些都无需内部化扩展插件。

但是,大多数情况下,类包装只是名称空间的替代。


-4

抱怨您未编写的代码有什么意义?

如果您不喜欢该代码,请编写自己的代码!

简单。问题解决了。

程序员喜欢按照自己的方式做事。因此,不要以为您可以告诉他们如何编写代码,要喝哪种威士忌,要吸烟的香烟品牌或要遵循的宗教信仰。他们只是调试这种透析仪,并继续做他们想做的事情。;-)

代码不是诗歌。代码是Sinatra歌曲“ My Way”的一种变体...


10
这个问题不是在抱怨代码,而是在要求对为什么以特定方式编写代码进行清晰的解释。WP核心大部分是过程性的,使用OOP方法具有一些较新的功能。许多现代插件还使用OOP封装功能。但是大多数主题都不是。OP询问为什么要使用伪OOP方法,并以Hybrid为例。您没有回答问题,只是在抱怨。
EAMann 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.