我的程序需要做两件事情。
从网页中提取的东西。
做的东西与网页。
然而,也有很多的网页,如Twitter和Facebook。
我应该这样做?
def facebookExtract():
code here
def twitterExtract():
code here
def myspaceExtract():
code here
def facebookProcess():
code here
def twitterProcess():
code here
def myspaceProcess():
code here
或者,我应该有某种类的? 如果是,则建议使用类,而当它建议只使用功能?
我最喜欢的经验法则:如果你怀疑是(不言而喻的假设:“你是个理智的人,而不是一个狂热的” ;-),制造和使用的一些类。 我经常发现自己重构最初写成简单的功能集成到类代码 - 例如,任何时候简单的功能与每个人交流最好的办法是与全局,这是一个代码味道,强烈暗示,该系统的保理不是真的好 - 而且往往重构的OOP方式是一个合理的定位。
Python是多范式,但其中央范例是OOP(很像,比方说,C ++)。 当一个程序或功能的方法(可能通过发电机&C)是最佳的系统的某些部分,通常脱颖而出 - 例如,静态函数也是一个代码的气味,如果你的类有那些的任何大量与暗示重构事情,以避免这一要求。
因此,假设你把所有的范式的把握丰富的Python得到 - 如果你有疑问还在,这说明你可能想要去OOP为您的系统的一部分! 只是因为Python支持OOP更完全比它支持函数式编程等。
从你的骨骼非常代码,在我看来,每个提取物/进程对属于一起,可能需要沟通的状态,所以一小部分与开采和加工方法的类似乎是天作之合。
“我的程序需要做两件事情。”
当你开始喜欢的是,对象不能被看到。 你的观点是不正确的。
改变你的思维。
“我的计划有东西的作品”
这是OO思想。 什么“东西”做你的工作方案与? 定义的东西。 这些都是你的基本类。 有对每种东西的类。
“我的计划从各种渠道得到的东西”
有每个源的类。
“我的程序显示的东西”
这通常是的东西存取方法加上收集的东西部分,以显示它的一些“报道”类的组合。
当你开始定义的“东西”,而不是“做”,你正在做的面向对象编程。 OO适用于一切,因为每一个方案涉及“做”和“东西”。 您可以选择的是“做” POV(这可能是程序或功能),或者你可以选择的“东西” POV(这是面向对象的。)
由你决定。 我亲自尝试在Python编程时从Java风格类望而却步。 相反,我使用类型的字典和/或简单的对象。
例如,把这些功能(你在问题中定义的)之后,我想创建一个简单的字典,也许是这样的:
{ 'facebook' : { 'process' : facebookProcess, 'extract': facebookExtract },
.....
}
或者,更好的是,使用自省来自动获取进程/提取功能:
def processor(sitename):
return getattr(module, sitename + 'Process')
def extractor(sitename):
return getattr(module, sitename + 'Extractor')
其中module
是当前模块(或具有这些功能的模块)。
为了得到这个模块作为一个对象:
import sys
module = sys.modules[__name__]
假设当然,通用的主要功能确实是这样的:
figure out sitename based on input.
get the extractor function for the site
get processor function for the site
call the extractor then the processor
把尽可能多的共同的东西一起在一个单一的功能。 一旦你分解为多出的可能,建立一个机制,分支到每个网站相应的功能。
一种可能的方式做,这是Python的if/else
子句,但如果你有很多这样的功能,你可能想要的东西更优雅如
F = __import__('yourproject.facebookmodule')
这可以让你把那具体为在自己的区域Facebook的代码。 既然你通过__import__()
的字符串,你可以根据你所访问的站点修改在运行时,然后只需要调用函数F在通用的工作程序代码。
更多关于这里: http://effbot.org/zone/import-confusion.htm
您可以使用OOP当它是有道理的,当它使开发解决方案更快,当它使得最终的结果更容易阅读,理解和维护。
在这种情况下,它可能是有意义的创建一个通用的接口提取/类,然后让Twitter的,MySpace和Facebook的等子类,但这真的取决于如何提取现场具体是。 这种抽象的想法是要隐藏这些细节。 如果你能做到这一点,这是有道理的。 如果你不能,你可能需要不同的方法。
它也可能是类似的好处是可以从程序的解决方案的良好分解来获得。
记得在这一天,所有的这些东西都只是工具的结束。 挑选而不是挑选锤,然后试图把一切都变成钉子针对特定职位的最佳之一。
我经常定义类解决的几个原因的问题,我会在下面的模型我的思想的一个例子。 我不知道混合OO模型和程序风格内疚,更多的是经常工作社会,而不是个人信仰的反映。 它往往工作有程序的门面一类层次结构如果这就是其他维护者期待。 (请原谅PHP语法)。
我开发战略,我可以按照一个通用模型。 所以,你的任务的可能的建模可能涉及得到的东西来啃过的网址。 如果你想简化外部逻辑很多,并删除条件语句这工作。 这表明,我可以使用DNRY的聚集()方法。
// batch process method
function MunchPages( $list_of_urls )
{
foreach( $list_of_urls as $url )
{
$muncher = PageMuncher::MuncherForUrl( $url );
$muncher->gather();
$muncher->process();
}
}
// factory method encaps strategy selection
function MuncherForUrl( $url )
{
if( strpos( $url, 'facebook.com' ))
return new FacebookPageMuncher( $url );
if( ... )
return new .... ;
}
// common tasks defined in base PageMuncher
class PageMuncher
{
function gather() { /* use some curl or what */ }
function process() {}
}
class FacebookPageMuncher extends PageMuncher
{
function process() { /* I do it 'this' way for FB */ }
}
我创建了一套理想地隐藏起来,更好的套路,共享。 这方面的一个例子可能是具有类,定义了常见的任务工具箱的方法。 更具体的任务可以扩展工具箱开发自己的行为。
class PageMuncherUtils
{
static function begin( $html, $context )
{
// process assertions about html and context
}
static function report_fail( $context ) {}
static function exit_retry( $context ) {}
}
// elsewhere I compose the methods in cases I don't wish to inherit them
class TwitterPageMuncher
{
function validateAnchor( $html, $context )
{
if( ! PageMuncherUtils::begin( $html, $context ))
return PageMuncherUtils::report_fail( $context );
}
}
我想整理我的代码,以传达更广泛意义的维护者。 想想看,如果我有连一个远程服务,我用的接口,我可能会潜入他们的界面中不同的API,而且我想随团类似主题的那些套路。 下面,我将展示一个例子,我怎么样去定义定义通用常量类,一类定义基本的服务方法,以及天气警报更具体的类,因为警报应该知道如何对自己进行刷新,这是一个比天气更具体服务本身,而且还利用WeatherAPI常数为好。
class WeatherAPI
{
const URL = 'http://weather.net';
const URI_TOMORROW = '/nextday/';
const URI_YESTERDAY= '/yesterday/';
const API_KEY = '123';
}
class WeatherService
{
function get( $uri ) { }
function forecast( $dateurl ) { }
function alerts( $dateurl )
{
return new WeatherAlert(
$this->get( WeatherAPI::URL.$date
."?api=".WeatherAPI::API_KEY ));
}
}
class WeatherAlert
{
function refresh() {}
}
// exercise:
$alert = WeatherService::alerts( WeatherAPI::URI_TOMORROW );
$alert->refresh();
文章来源: General programming question. When to use OOP?