标签: solid-principles

DDD存储库和工厂

从Matt Petters那里读过一篇关于DDD博客

并据说我们为每个实体创建一个存储库(接口),然后我们创建一个RepositoryFactory,它将提供存储库的实例(声明为接口)

这是使用DDD完成项目的方式吗?

我的意思是,我看到我认为他们使用DDD但他们直接调用每个存储库的项目,没有涉及工厂

并且

为什么我们需要创建这么多的存储库类,为什么不使用类似的东西

public interface IRepository : IDisposable
{
T[] GetAll();
T[] GetAll(Expression<Func> filter); 
T GetSingle(Expression<Func> filter); 
T GetSingle(Expression<Func> filter, List<Expression<Func>> subSelectors); 
void Delete(T entity); 
void Add(T entity); 
int SaveChanges(); 
}
Run Code Online (Sandbox Code Playgroud)

我想这可能是违反SOLID原则或其他原因的东西?

domain-driven-design solid-principles

3
推荐指数
1
解决办法
1099
查看次数

ToString()方法是否违反了SRP?

正如标题所述,为什么任何对象应该继承ToString()方法(例如在C#或Java中)并以某种方式关注将其转换为String?在某些情况下,这不违反单一责任原则吗?我的意思是,如果你的对象不需要转换为字符串,你最终会对你的对象有更多的响应能力.

c# java oop single-responsibility-principle solid-principles

3
推荐指数
1
解决办法
334
查看次数

一种在超类中实例化子类的方法

我有一个基本抽象类,它聚合了一个集合中的一堆项目:

abstract class AMyAbstract
{
    List<string> Items { get; private set; }

    public AMyAbstract(IEnumerable<string> items)
    {
        this.Items = new List<string>(items);
    }
}
Run Code Online (Sandbox Code Playgroud)

有很多子类,让我们为它们命名Foo,Bar,Baz,等他们都是一成不变的.现在我需要一个merge()方法,它将合并items两个对象,如下所示:

abstract class AMyAbstract
{
    // ...
    public AMyAbstract merge(AMyAbstract other)
    {
        // how to implement???
    }
}

Foo foo1 = new Foo(new string[] {"a", "b"});
Bar bar1 = new Bar(new string[] {"c", "d"});
Foo fooAndBar = foo1.merge(bar1);
// items in fooAndBar now contain: {"a", "b", …
Run Code Online (Sandbox Code Playgroud)

oop design-patterns dry single-responsibility-principle solid-principles

3
推荐指数
1
解决办法
203
查看次数

依赖注入/ SOLID担心

我有一个用C#编写的Web API应用程序.我正在努力确保设计符合SOLID原则.因此我使用Unity将依赖项注入我的控制器.但是我希望将控制器执行的操作从控制器本身中取出,因此它们实际上只是在其他(通常是静态的)对象上调用方法.例如:

public class MyController : ApiController
{
    private readonly ISomeCrossCuttingInterface _instance;
    private readonly ILog _log;

    public MyController(ISomeCrossCuttingInterface someInterface, ILog log)
    {
        _instance = someInterface;
        _log = log;
    }

    [HttpPost]
    [ActionName("MyAction")]
    public RequestResponse MyAction(MyActionData actionData)
    {
        try
        {
            return MyActionUser(actionData);
        }
        catch (Exception ex)
        {
            _log.Error("MyAction error", ex);
        }
        return ...;
    }

    private RequestResponse MyActionUser(MyActionData actionData)
    {
        var responseObj = StaticClass.SomeMethod(_instance, actionData);
        var responseObj2 = StaticClass2.SomeMethod(_instance, responseObj2);
        return CreateMyActionResponse(responseObj2);
    }

    private RequestResponse CreateMyActionResponse(...)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的一些焦虑是用于执行工作的对象(例如上面的StaticClass和StaticClass2)是否应该实际注入.目前他们不是.已注入的对象是与交叉切割问题相关的对象,例如日志记录或数据访问,或由多个控制器使用的对象.那么为什么我不注入执行工作的对象呢?我认为这些"内部"对象仅用于执行与一个控制器相关的特定工作.也就是说,控制器功能基本上被分解为具有单一责任的对象,每个控制器都拥有自己独特的对象集,无论控制器需要做什么.不过这是一个糟糕的设计吗?是否应该注射所有物体?任何输入真的很感激.

c# dependency-injection solid-principles asp.net-web-api

3
推荐指数
1
解决办法
317
查看次数

向子类添加公共方法是否违反LSP(Liskov替换原则)?

如果我将子方法添加到子类并且客户端程序调用添加的方法,则客户端程序不能使用父对象而不是子类.

import unittest

class BaseClass(object):

    def doSomething(self):
        pass


class SubClass(BaseClass):

    def doStuff(self):
        pass

class Client(object):

    def __init__(self, obj):
        self.obj = obj

    def do(self):
        self.obj.doStuff()

class LSPTestCase(unittest.TestCase):

    def test_call_subclass_method(self):
        client = Client(SubClass())
        client.do()

    def test_call_baseclass_method(self):
        client = Client(BaseClass())
        with self.assertRaises(AttributeError):
            client.do()

if __name__ == '__main__':
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

这种情况违反了LSP?

oop liskov-substitution-principle solid-principles

3
推荐指数
1
解决办法
505
查看次数

如果重写方法返回不同的值,是否违反了Liskov原则?

下面是我的基类,它有ReturnAddress方法,返回'地址一',在子类中重写覆盖返回'地址二'的相同方法.

public class Base     
{         
     public virtual string ReturnAddress()        
     {             
         return "Address one";         
     }    
 }    


public class Derived : Base     
{                  
    public override string ReturnAddress()         
     {             
        return "Address Two";         
     }
}

//Object declaration for base and derived

Base base = new Base();

Derived der = new Derived();

var result = der.ReturnAddress(); // will return "Address Two"
but if we replace der object with base object 

var result = base.ReturnAddress(); //Will return "Address One"
Run Code Online (Sandbox Code Playgroud)

因此父对象无法替换子对象.

我想知道这是破坏Liskov原理的例子吗?

c# oop solid-principles

3
推荐指数
1
解决办法
316
查看次数

开闭原则和继承的区别

我知道开闭原则意味着对扩展开放,对修改封闭。考虑如下示例

public class Vehicle{
    public void service(){
        //vehicle servicing code
    }
}

public class Bike extends Vehicle{

    public void service(){
        // bike specific servicing 
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我明白Bike该类Vehicle使用开放封闭原则扩展并添加了新功能。

考虑我创建Vehicle类的jar 文件,然后类从 jarBike扩展Vehicle类。在这种情况下,我们不能修改Vehicle类并Bike扩展它。这是开闭原则的一个很好的例子吗?我想知道 OCP 与继承有何不同

polymorphism inheritance abstraction open-closed-principle solid-principles

3
推荐指数
1
解决办法
1255
查看次数

未来证明:删除 JSON 信封是当前的最佳实践吗?

我已经阅读了关于您是否应该删除 JSON 请求或回复中的信封的相互矛盾的“意见”。

例子:

{
    "data": {
        "foo" : "bar",
        "baz" : "Xyzzy"
    }
}
Run Code Online (Sandbox Code Playgroud)

应该(据说)写成:

{
    "foo" : "bar",
    "baz" : "Xyzzy"
}
Run Code Online (Sandbox Code Playgroud)

但是,按照 SOLID 原则,这个结构应该对扩展开放,对修改关闭。因此,移除信封将是一个坏主意。对?

如果稍后我决定需要向入站 JSON 信息添加更多信息,那么这样做会更简洁:

{
    "data": {
        "foo" : "bar",
        "baz" : "Xyzzy"
    },

    "extended-data": {
        "abc" : 123
    }
}
Run Code Online (Sandbox Code Playgroud)

比这样做:

{
    "foo" : "bar",
    "baz" : "Xyzzy",
    "abc" : 1234
}
Run Code Online (Sandbox Code Playgroud)

前者允许先前编写的代码,它会查找“数据”节点以执行而不会出现故障或更改。后者要求重新编写代码以查找新值。

当前的最佳实践是什么,请提供您的来源:我需要公认的标准而不是意见。

更新:

回答异议:“如果添加字段,则必须更改代码。”

并不真地。我不必更改代码来处理新字段,我只需要为新数据添加一个新处理程序:

例子:

function delegateTask($json) {
    $this->doSomething($json->data);
}
Run Code Online (Sandbox Code Playgroud)

扩展后:

function delegateTask($json) {
    $this->doSomething($json->data);
    $this->doSomethingElse($json->extended);
}
Run Code Online (Sandbox Code Playgroud)

如果我只使用 …

rest json solid-principles

3
推荐指数
1
解决办法
2002
查看次数

C# 中对象健美操第一类集合规则的示例?

我正在玩对象健美操规则,在使用 C# 时,我在查看何时使用第一类集合时遇到了一些麻烦。

我的意思是我几乎看不到什么时候应该使用它,例如很难将该规则应用于 EF DbContext

比方说,我们设计了一个 Board 类。

public class Board
{
    public IList<BoardRow> Rows { get; }
    public IList<BoardColumn> Columns { get; }

    public Board()
    {
        Rows = new List<BoardRow>();
        Columns = new List<BoardColumn>();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以根据这个规则,我们必须把上面的代码变成:

// Is it really that better than just using List<BoardRow>?
public class BoardRowCollection : IEnumerable<BoardRow>
{
    public void Add(BoardRow row) { /*...*/ }
    public void Remove(BoardRow row) { /*...*/ }

    // IEnumerable<BoardRow> Impl goes here...
}

// Is it really …
Run Code Online (Sandbox Code Playgroud)

c# oop design-patterns solid-principles

3
推荐指数
1
解决办法
1237
查看次数

我们可以在Laravel控制器中拥有两个或多个类吗

考虑到接口隔离原理,它是面向对象编程中最“被谈论的”原理之一-SOLID原理,我想知道在单个Laravel控制器中是否可以有两个不同的类?例如:

  <?php

    namespace ...;

    use App\Http\Controllers\Controller;

    interface VehicleInterface
    {
      public function ...
    }

    class CarController extends Controller implements VehicleInterface
    {
       ...
    }

    class ElectricCar implements VehicleInterface
    { 
       ...
    }
Run Code Online (Sandbox Code Playgroud)

php solid-principles laravel laravel-5.2

3
推荐指数
1
解决办法
276
查看次数