我的代码位于此处:https://github.com/maniator/SmallFry
我是否应该让 App 类不必使用静态函数,但同时能够从任何地方为应用程序设置和设置变量?
或者我应该使用 App::get 和 App::set 方法保持它现在的样子吗?
两者各有什么优缺点?
如果我要承担第一项任务,我将如何完成?
示例代码:
//DEFAULT TEMPLATE
App::set('APP_NAME', 'SmallVC');
//END DEFAULT TEMPLAT
//
//DEFAULT TEMPLATE
App::set('DEFAULT_TEMPLATE', 'default');
//END DEFAULT TEMPLATE
//DEFAULT TITLE
App::set('DEFAULT_TITLE', 'Small-VC');
//END DEFAULT TITLE
//LOGIN SEED
App::set('LOGIN_SEED', "lijfg98u5;jfd7hyf");
//END LOGIN SEED
App::set('DEFAULT_CONTROLLER', 'AppController');
if(App::get('view')){
$template_file = $cwd.'/../view/'.App::get('view').'/'.App::get('method').'.stp';
if(is_file($template_file)){
include $template_file;
}
else {
include $cwd.'/../view/missingview.stp'; //no such view error
}
}
else {
App::set('template', 'blank');
include $cwd.'/../view/missingfunction.stp'; //no such function error
}
最佳答案
我想你有一种感觉,静电不好。我发布的内容可能看起来相当疯狂,因为它是一个巨大的变化。至少希望它能展示一个不同的世界观。
Miško Hevery 写道 static methods are a death to testability .
我喜欢测试,因此我不使用它们。那么,我们还能如何解决这个问题呢?我喜欢使用我认为是一种依赖注入(inject)的方式来解决它。 Martin Fowler 有一篇很好但很复杂的文章 here .
对于构造中的每个对象,我传递了它们运行所需的对象。根据您的代码,我将使 AppController 变为:
class AppController
{
protected $setup;
public function __construct(array $setup = array())
{
$setup += array('App' => NULL, 'Database' => NULL);
if (!$setup['App'] instanceof App)
{
if (NULL !== $setup['App'])
{
throw new InvalidArgumentException('Not an App.');
}
$setup['App'] = new App();
}
// Same for Database.
// Avoid doing any more in the constructor if possible.
$this->setup = $setup;
}
public function otherFunction()
{
echo $this->setup['App']->get('view');
}
}
依赖项默认为最有可能的值(您在 if 语句中的默认构造)。所以,通常你不需要通过设置。但是,当您正在测试或需要不同的功能时,您可以传入模拟或不同的类(派生自正确的基类)。您也可以选择使用接口(interface)。
编辑 更纯粹的依赖注入(inject)形式涉及进一步的变化。它要求您始终传递所需的对象,而不是在未传递对象时让类默认一个。我在 +20K LOC 的代码库中经历了类似的更改。实现之后,我看到了一路走来的许多好处。对象封装得到了极大的改进。它让您感觉自己拥有真实的对象,而不是每一段代码都依赖于其他东西。
当您没有注入(inject)所有依赖项时抛出异常会使您快速修复问题。通过在一些 Bootstrap 代码中使用 set_exception_handler 设置一个良好的系统范围异常处理程序,您将很容易看到您的异常并可以快速修复每个异常。 AppController 中的代码变得更简单,构造函数中的检查变为:
if (!$setup['App'] instanceof App)
{
throw new InvalidArgumentException('Not an App.');
}
对于每个类,您随后编写的所有对象都将在初始化时构建。此外,对于对象的每个构造,您将传递所需的依赖项(或让您提供的默认依赖项)被实例化。 (当您忘记这样做时您会注意到,因为您将不得不重写代码以在测试之前删除依赖项。)
这看起来工作量很大,但类(class)更接近真实世界,测试变得轻而易举。您还可以在构造函数中轻松查看代码中的依赖项。
关于php - 我应该从我的代码中删除静态函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676515/
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin