将参数中的字段传递给外部方法调用是不是违反了打开/关闭原则?
Posted
技术标签:
【中文标题】将参数中的字段传递给外部方法调用是不是违反了打开/关闭原则?【英文标题】:Does passing a field in a parameter to an external method call violate the Open/Closed principle?将参数中的字段传递给外部方法调用是否违反了打开/关闭原则? 【发布时间】:2016-04-27 19:56:11 【问题描述】:在下面的代码中,从 class Foo
传递私有成员 _field
作为外部方法参数 (Bar.DoSomething(_field)
) 是否违反了 SOLID 编程实践中的 Open/Closed principle?
在面向对象编程中,开/关原则状态 “软件实体(类、模块、函数等)应该是开放的 扩展,但关闭修改”;也就是说,这样一个 实体可以允许其行为被扩展而不修改其 源代码。
据我了解,实体应该对扩展开放,但对修改关闭。但是,在这种情况下,_field
在Foo
的构造函数中设置了一次,并且是readonly
。 将私有成员传递给外部方法的参数是否违反了开放/封闭原则或其他一些最佳实践?
public class Foo
private readonly int _field;
public Foo(int input)
_field = input;
private void FooDoSomething()
Bar.BarDoSomething(_field); //Breaking Open/Closed Principle?
public static class Bar
public static void BarDoSomething(int input)
//Something happens
【问题讨论】:
我建议你把这个问题转发到programmers.stackexchange.com。 @Xiaoy312 cross-posting is frowned upon @gnat 我认为 migrate 是我应该使用的词。 【参考方案1】:不,这不违反开放/封闭原则。从Bar
的角度来看,input
不是属于Foo
的内部字段。它只是一个整数。 Foo
的内部状态仍然隐藏在类中。
更进一步,除非您在传递参数时指定ref
,
Bar.BarDoSomething(ref _field);
Bar
甚至不能修改_field
的值。交互是单向的。 Foo
告诉 Bar
做某事。那挺好的。
澄清一下——即使使用了ref
并且Bar
可以修改与打开/关闭原则没有任何关系的值。但是,如果Bar.DoSomething
的目的是返回一个值,那么作为一个返回int
的函数而不是修改一个值的方法会更好。这样调用者可以获取值并决定是否要更新_field
。
【讨论】:
我对这篇文章的解释完全不同——据我了解,任何非密封类都是开放的(用于扩展),因为它可以在不修改其源代码的情况下进行扩展(通过继承)。但是,我不确定如何解释“关闭”... 在所问问题的上下文中 - 没有以任何方式涉及行为修改,所以我会说即使非最终变量会通过引用进行修改,也不会违反原则.我是不是理解错了? 我无法从示例中得出与开放/封闭原则之间的关系,因为该示例甚至没有真正处于违反或不违反该原则的范围内。所以我只是回答,“不,它不违反它。”我可以理解为什么会出现这个问题。但即使修改了值,它也不会与该原则有任何关系。 在实践中,我将“封闭”部分理解为意味着即使派生类也隐藏了类的内部。因此,如果您从Foo
继承,那么 base 类可以修改_field
,但派生类不能。因此,虽然您可以扩展它的行为,但您仍然可以将继承的类强制转换为 Foo
并相信它的行为方式完全相同。例外情况是那些打算被覆盖的方法,但您仍然想确定这些被覆盖的方法可以或不能在对象的内部状态中改变什么。
那么我们是否可以同意——如果我们是严格的——如果一个类不包含任何虚方法,它就会被关闭? (这将消除异常。)以上是关于将参数中的字段传递给外部方法调用是不是违反了打开/关闭原则?的主要内容,如果未能解决你的问题,请参考以下文章
String在方法中的传递方式(调用外部方法给String变量赋值时,未得到预期结果)