Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 什么是不透明依赖关系?_Design Patterns_Anti Patterns - Fatal编程技术网

Design patterns 什么是不透明依赖关系?

Design patterns 什么是不透明依赖关系?,design-patterns,anti-patterns,Design Patterns,Anti Patterns,我正在阅读有关设计模式的文章,我注意到术语“不透明依赖项”被大量使用。 一些消息来源说: 不透明依赖是一种糟糕的依赖 不透明依赖项是不能使用类的 公共API 但我不太明白 有人能给我一些使用这种依赖关系的例子吗?我为什么要避免它们?例如: public class MyService { private IRepository repo = new Repository(); public MyService() { repo = new Reposit

我正在阅读有关设计模式的文章,我注意到术语“不透明依赖项”被大量使用。 一些消息来源说:

不透明依赖是一种糟糕的依赖

不透明依赖项是不能使用类的 公共API

但我不太明白

有人能给我一些使用这种依赖关系的例子吗?我为什么要避免它们?

例如:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService()
    {
        repo = new Repository();
    }
} 
public class MyService
{
    private ISomeContext context;

    public MyService(ISomeContext context)
    {
        this.context = context;
    }

    public void DoSomethingUseful()
    {
        var repository = this.context.CreateRepository<IRepository>();

        repository.Save(new X());
    }
}
repo
将被归类为不透明依赖项,因为没有(简单的)方法来改变它,例如在单元测试中

这是相同的示例,但作为透明依赖项:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService(IRepository repositoryDependency)
    {
        repo = repositoryDependency;
    }
} 
在这里,我们可以传递我们自己的
IRepository
并测试
MyService
的行为,而DI容器之类的工具可以为我们设置依赖项,这在不透明示例中是无法实现的。

例如:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService()
    {
        repo = new Repository();
    }
} 
public class MyService
{
    private ISomeContext context;

    public MyService(ISomeContext context)
    {
        this.context = context;
    }

    public void DoSomethingUseful()
    {
        var repository = this.context.CreateRepository<IRepository>();

        repository.Save(new X());
    }
}
repo
将被归类为不透明依赖项,因为没有(简单的)方法来改变它,例如在单元测试中

这是相同的示例,但作为透明依赖项:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService(IRepository repositoryDependency)
    {
        repo = repositoryDependency;
    }
} 

在这里,我们可以传入我们自己的
IRepository
并测试
MyService
的行为,而DI容器之类的工具可以为我们设置依赖项,这在不透明示例中是无法实现的。

不透明依赖项是隐藏的。不透明依赖的反面是显式依赖

不透明的依赖关系是不好的,因为使用类的开发人员可能没有意识到这种依赖关系的存在。当它们调用各种方法时,可能会产生意想不到的副作用

不透明依赖项

public class Users
{
    private Database database;

    public Users()
    {
        this.database = new SqlDatabase(...);
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
public class Users
{
    private Database database;

    public Users(Database database)
    {
        this.database = database;
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
显式依赖关系

public class Users
{
    private Database database;

    public Users()
    {
        this.database = new SqlDatabase(...);
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
public class Users
{
    private Database database;

    public Users(Database database)
    {
        this.database = database;
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}

不透明依赖项是隐藏的依赖项。不透明依赖的反面是显式依赖

不透明的依赖关系是不好的,因为使用类的开发人员可能没有意识到这种依赖关系的存在。当它们调用各种方法时,可能会产生意想不到的副作用

不透明依赖项

public class Users
{
    private Database database;

    public Users()
    {
        this.database = new SqlDatabase(...);
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
public class Users
{
    private Database database;

    public Users(Database database)
    {
        this.database = database;
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
显式依赖关系

public class Users
{
    private Database database;

    public Users()
    {
        this.database = new SqlDatabase(...);
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}
public class Users
{
    private Database database;

    public Users(Database database)
    {
        this.database = database;
    }

    public User Find(int userId)
    {
        return database.GetById(...);
    }
}

基于@NikolaiDante的答案,我想补充一点,即不透明依赖可以通过透明依赖引入

例如:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService()
    {
        repo = new Repository();
    }
} 
public class MyService
{
    private ISomeContext context;

    public MyService(ISomeContext context)
    {
        this.context = context;
    }

    public void DoSomethingUseful()
    {
        var repository = this.context.CreateRepository<IRepository>();

        repository.Save(new X());
    }
}
公共类MyService
{
私人语境;
公共MyService(上下文)
{
this.context=上下文;
}
公共无效dosomethingusive()
{
var repository=this.context.CreateRepository();
Save(新的X());
}
}
<>虽然,对<代码> ISOMCONTEXT/<代码>的依赖是透明的,但它隐藏了一个事实:它用于解决<代码> IRepository < /代码>,我现在认为它是不透明的依赖关系。依我看,这降低了班级设计的“纯洁性”,通常是为了方便或懒惰


在“挖掘合作者”一节中有更多关于这类问题的内容。

基于@NikolaiDante的答案,我想补充一点,即不透明依赖可以通过透明依赖引入

例如:

public class MyService
{
    private IRepository repo = new Repository();

    public MyService()
    {
        repo = new Repository();
    }
} 
public class MyService
{
    private ISomeContext context;

    public MyService(ISomeContext context)
    {
        this.context = context;
    }

    public void DoSomethingUseful()
    {
        var repository = this.context.CreateRepository<IRepository>();

        repository.Save(new X());
    }
}
公共类MyService
{
私人语境;
公共MyService(上下文)
{
this.context=上下文;
}
公共无效dosomethingusive()
{
var repository=this.context.CreateRepository();
Save(新的X());
}
}
<>虽然,对<代码> ISOMCONTEXT/<代码>的依赖是透明的,但它隐藏了一个事实:它用于解决<代码> IRepository < /代码>,我现在认为它是不透明的依赖关系。依我看,这降低了班级设计的“纯洁性”,通常是为了方便或懒惰


在“深入协作者”一节中有更多关于这类问题的内容。

这意味着主要缺点来自单元测试?这意味着主要缺点来自单元测试?所有答案都给了我关键信息。现在我不确定哪一个是正确答案。所有的答案都给了我关键信息。现在我不确定哪一个是正确答案。