我试图了解真正定义紧耦合的原因.我已经阅读了很多关于这个主题的帖子,但有一件事仍然不适合我.
我理解应该使用接口而不是具体实现将类注入其他类.我也理解,如果一个类遵循一个接口,那么任何使用注入接口的类都可以调用接口中定义的公共函数并期望类似的功能.
interface iFormatter()
{
public function format(array $order): array
}
public class OrderFormatter implements iFormatter
{
public function format(array $order): array
{
// ...
return $formattedArray;
}
}
public class OrderGenerator implements iGenerator
{
private $formatter;
public function __construct(iFormatter $formatter)
{
$this->formatter = $formatter;
}
public function generate()
{
// ...
return $this->formatter->format($order);
}
}
Run Code Online (Sandbox Code Playgroud)
所以我认为在只有格式化器改变的情况下,这将被定义为松散耦合;
$example = new OrderGenerator(new CarOrderFormatter);
$example->generate();
$example = new OrderGenerator(new VanOrderFormatter);
$example->generate();
Run Code Online (Sandbox Code Playgroud)
我不太清楚的是,当你把责任从彼此中抽离出来时,这些课程仍然紧密相连.就像是
$example = …Run Code Online (Sandbox Code Playgroud) 在 Laravel 中使用Route::resource()控制器时包含 7 个方法。我不确定edit和update方法/资源之间有什么区别。
GET /resource/{resource}/edit edit resource.edit
PUT/PATCH /resource/{resource} update resource.update
Run Code Online (Sandbox Code Playgroud)
在我对 REST 的理解中,laravel 的update实现似乎是相当标准的,而edit在将资源作为 JSON 返回时,我无法想到使用它的场景。
我有一个扩展基数组类的自定义数组类.我有一个易于使用的自定义方法
export class ExampleArray extends Array {
includesThing(thing) {
...
return false
}
}
Run Code Online (Sandbox Code Playgroud)
但是filter,map等的现有方法返回数组的实例.我想ExampleArray用这些方法返回一个实例.
我可以找到这些方法的接口,但不能找到它们的实现.如何调用父方法并返回我的自定义EampleArray?像下面这样的东西
export class ExampleArray extends Array {
filter() {
result = Array.filter()
array = new ExampleArray()
array.push(...result)
return array
}
Run Code Online (Sandbox Code Playgroud)
或者这是扩展数组以制作自定义数组的正确方法吗?
我正在尝试/etc/hosts使用ansibles 在我的文件中添加一个条目lineinfile.我希望逻辑是如果它找到条目127.0.0.1 mysite.local然后什么也不做,否则在行之后插入它127.0.1.1
127.0.0.1 localhost
127.0.1.1 mypc
127.0.0.1 mysite.local
Run Code Online (Sandbox Code Playgroud)
部分工作后我有插入但看起来实际的正则表达式搜索无法找到现有的条目,所以我不断重复插入 127.0.0.1 mysite.local
文档确实说;
修改一行时,正则表达式通常应匹配行的初始状态以及更换后的行状态,以确保幂等性.
但我不确定这对我的正则表达式有何影响.目前我的戏是;
- name: Add the site to hosts
lineinfile:
path: /etc/hosts
# Escape special chars
regex: "^{{ domain|regex_escape() }}"
line: "127.0.0.1 {{ domain }}"
insertafter: '127\.0\.1\.1'
firstmatch: yes
become: yes
Run Code Online (Sandbox Code Playgroud)
哪里domain是mysite.local.
我看过这个答案,但我很确定backrefs自从文档说明以来我无法使用;
该标志稍微改变了模块的操作; insertbefore和insertafter将被忽略,如果正则表达式与文件中的任何位置不匹配,则文件将保持不变.
我试过了;
regex: '127\.0\.0\.1\s+?{{ domain|regex_escape() }}'
Run Code Online (Sandbox Code Playgroud)
也没有运气
快速搜索一个看似微不足道的问题,但无济于事.我想基本上测试另一个数组中的数组中的字符串元素是数字还是只是字符.所以我使用parseInt转换字符串,它返回'int'或'NaN'.
但是如果我使用if语句;
if (typeof (parseInt(a_data[j][i])) == "number")
{
console.log(parseInt(a_data[j][i]) + " is a number.")
}
Run Code Online (Sandbox Code Playgroud)
然后打印出它后,它开始打印出"NaN是一个数字".我已经使用了这个;
if (!isNaN(parseInt(a_data[j][i])))
{
console.log(parseInt(a_data[j][i]) + " is a number.")
}
Run Code Online (Sandbox Code Playgroud)
但我想知道为什么认为NaN是一个数字?
我正在学习OOP,特别是接口.我也在尝试学习SOLID,在这种情况下是D.
从这个站点,初始程序实现了'concretion' - 在这种情况下PDFBook是typehinted传递给构造函数.稍后,此类型提示将更改为常规EBook界面.接受任何实现此接口的内容.在这种情况下有道理.
但是,即使在对接口进行编码时,我发现通常还没有在接口中定义额外的方法,但这些方法对于该结构是唯一的.在这种情况下,PDFBook可能有一个doDPFOnlyThing未在实现该EBook接口的任何其他类中定义的方法.
如果我传递一个类型提示接口的PDFBook对象,根据我的理解,如果我只使用接口中定义的方法- 那么这会坚持DIP是吗?因此,任何传递给实现接口的东西都可以调用它们的方法,因为它遵守接口契约.myFunc()EBookread()myFunc()read()
myFunc(Ebook $book) {
$book->read();
}
Run Code Online (Sandbox Code Playgroud)
如果只能在PDFBook类中myFunc()使用doDPFOnlyThing(),该怎么办?我假设这会添加依赖关系,因为这种方法只存在于PDFBook具体结果中?
myFunc(Ebook $book) {
$book->doDPFOnlyThing();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,做什么更好?
以前从来没有必要做这么基本的事情。在执行逻辑之前如何将变量初始化为浮点数?这两个例子有意义吗?
$var = 0.0;
$var = (float) 0;
Run Code Online (Sandbox Code Playgroud) 我正在使用带有ansible playbook的vagrant在ubuntu映像上自动安装一堆程序.一个程序无法在vagrant VM上安装.在Vagrant我的文件中
config.vm.provision :ansible do |ansible|
ansible.verbose = "vvv"
ansible.playbook = "provisioning/playbook.yml"
end
Run Code Online (Sandbox Code Playgroud)
但是详细输出不包括apt-get输出.我的playbook.yml看起来像
---
- hosts: all
sudo: true
tasks:
- name: get vi
apt: state=latest name=vim
Run Code Online (Sandbox Code Playgroud)
如何apt-get install在VM上查看单个(或所有)的控制台输出,因为ansible会以格式输出每个安装
TASK: [Install vim] ***********************************************************
failed: [default] => {"failed": true}
...
Run Code Online (Sandbox Code Playgroud) 我有一些命名空间被在包A中使用自动加载的测试
"autoload-dev": {
"psr-4": {
"Vendor\\PackageA\\PhpUnit\\": "tests/PhpUnit"
}
},
Run Code Online (Sandbox Code Playgroud)
这很好用.
我有另一个包,包B也有命名空间测试,需要在包A中进行一个命名空间测试
"autoload-dev": {
"psr-4": {
"Vendor\\PackageB\\PhpUnit\\": "tests/PhpUnit"
}
},
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在包B中包含该文件时,找不到该类
use Vendor\PackageA\PhpUnit\MyTestFromA;
class MyTestFromB extends MyTestFromA
{
Run Code Online (Sandbox Code Playgroud)
让我觉得其他软件包中的autoload-dev东西没有被加载.
PHP致命错误:第3行的/full/path/to/PackageBClass.php中找不到类'Vendor\PackageA\PhpUnit\MyTestFromA'
当我尝试autoload从包B而不是导入使用自动加载的文件时autoload-dev,我没有得到任何错误.
我怎么能克服这个?
我的一部分是考虑为测试制作一个包,并在两者中自动加载,autoload-dev但我想先确认.
我在我的应用程序中使用Laravel 合约来将应用程序代码与框架代码分离。但主要是,我发现一目了然更容易看出班级做得太多——我们的遗留项目受到到处都是“隐藏的外观”的影响。
use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\Factory as File;
class MyClass extends Command
{
public function __construct(File $file)
{
$this->file = $file;
}
public function handle()
{
$this->file->put('/here.txt', 'stuff');
}
}
Run Code Online (Sandbox Code Playgroud)
当试图模拟它们时,问题就来了。如果我模拟合同并运行测试,则不会使用模拟代替合同。
use Illuminate\Contracts\Filesystem\Factory as File
MyClassTest
{
public function my_example_test()
{
$fileSystem = m::mock(File::class);
$fileSystem->shouldReceive('put')->once();
$this->app->instance(File::class, $fileSystem);
$this->artisan('my-custom-command');
}
}
Run Code Online (Sandbox Code Playgroud)
当我检查$file属性时,我当然可以看到 laravel 使用了具体的实现(显然)。除了当我尝试模拟具体实现时,它也被用来代替模拟。
use Illuminate\Config\Repository as File;
MyClassTest
{
public function my_example_test()
{
$fileSystem = m::mock(File::class);
$fileSystem->shouldReceive('put')->once();
$this->app->instance(File::class, $fileSystem);
$this->artisan('my-custom-command');
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试嘲笑两者,但这也不起作用。我正在做集成测试,因此为什么我使用 artisan 调用命令。显然,单元测试 …