很多人都知道这篇文章:更多关于 getter 和 setter。我认为它在描绘 getter/setter 的邪恶方面做得很有说服力。我还通过尝试将现有项目(未完成)转换为没有 getter/setter 的代码来测试它。有效。代码可读性大大提高,代码更少,我什至设法摆脱了最初认为它们确实有必要的 getter/setter。除了一处。
让模型进入视图部分是我认为这种方法没有抓住要点的地方。在文章中作者使用构建器导出模型。问题是:对放入构建器的内容的控制与使用 getter 获得的内容一样多。是的,它隐藏了实现,即它在模型中的表示方式。但是 getter 并没有从模型中取出与放入其中的非常不同的东西。如果您创建一个通过构造函数传递 '5' 的 Money 对象,money.getAmount() 将不会将此转换为其他货币或作为其中包含一个元素 '5' 的数组返回。
你设置什么就得到什么。通过视图,我们设置了值,以及当我们从一个应该保存我们首先设置的对象的对象中询问(获取)这些值时我们期望的值。导出这些的构建器只是期望相同。
这个问题有点长。但我想在我的观点上受到挑战。将模型数据传输到视图层的 getter 和 setter 是否邪恶?
有很多人认为 getter/setter 根本不是邪恶的。这也不是我想听到的辩护,因为我认为他们在我提到的其他地方确实是邪恶的。
我正在使用Linq DataContext.ExecuteQuery("some sql statement")来填充对象列表
var incomes = db.ExecuteQuery<IncomeAggregate>(sqlIncomeStatement(TimeUnit));
Run Code Online (Sandbox Code Playgroud)
这IncomeAggregate是我用来保存此查询记录结果的对象.
YQM是该对象的一个属性:
public int Year { get; set; }
public int Quarter { get; set; }
public int Month { get; set; }
public string YQM
{
get { return string.Format("Y{0}-Q{1}-M{2}", Year, Quarter, Month); }
}
... more properties
Run Code Online (Sandbox Code Playgroud)
一切都编译好,但当它执行Linq我得到以下错误:
无法为成员'YQM'分配值.它没有定义一个setter.
但显然,我不想"设定"它.Y,Q和M由查询提供给数据库.查询不提供YQM.我是否需要以某种方式更改对象的定义?(我刚开始使用Linq而且我还在加快速度,所以它可能非常简单)
说实话,我真的不知道,怎么问这个问题,所以请不要生气:)
无论如何,我想让我的类中的mutators(setter)返回this以允许类似jQuery,a.name("something").address("somethingelse");
我有一个父类(Entity)和几个子类(Client, Agent etc.).大多数事物的变换器都是从Entity类继承的(比如名称或地址),但它们返回一个Entity对象,所以我不能在它们上面调用Client mutators.
换一种说法:
// name mutator
Entity& Entity::name( const string& name ) {
// [...] checks
_name = name;
return *this;
}
// budgetRange mutator
Client& Client::budgetRange( const long int& range ) {
// [...] checks
_budgetRange = range;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
然后我打电话给它:
Client a; a.name("Dorota Adamczyk").budgetRange(50);
Run Code Online (Sandbox Code Playgroud)
编译器(逻辑上)说,Entity对象没有budgetRange成员(因为name返回一个Entity,而不是Client).
我现在的问题是:我怎么能实现这样的东西?我考虑过重载子类中的所有实体函数,但这不会很好,并且会违背继承的想法:)
提前感谢您的想法:D
为什么以下示例无法在setter方法中运行doctest ?
class Foo:
a = None
@property
def a(self):
pass
@a.setter
def a(self, v):
'''
>>> 1 == 1
False
'''
pass
if __name__ == "__main__":
import doctest
doctest.testmod()
Run Code Online (Sandbox Code Playgroud)
调试器确认没有运行测试(上面写的示例dtest.py):
>>> import dtest, doctest
>>> doctest.testmod(dtest)
TestResults(failed=0, attempted=0)
Run Code Online (Sandbox Code Playgroud)
正确执行getter方法中的相同测试,当然报告失败...
我知道如何像这样使用 JS 的 getter 和 setter 来处理对象属性
var myObject = {
value : 0,
get property() {
return this.value;
},
set property(v) {
this.value = v;
}
}
Run Code Online (Sandbox Code Playgroud)
这样调用myObject.property = 2就会设置myObject.value,但我想知道是否有某种方法可以调用myObject = 2并且仍然设置myObject.value而不是myObject从对象更改为数字。
这可能是不可能的,但 javascript 是一种非常灵活的语言,我想我会在放弃这个想法之前向社区提出这个问题。
假设我有一个 User 类
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int Level {get;set;}
}
User user1 = new User();
user1.Name = "name";
user1.Surname = "Surname";
user1.Level = 0;
User user2 = new User();
user2.Name = "name";
user2.Surname = "Surname";
Run Code Online (Sandbox Code Playgroud)
当我检查user1.Level == user2.Level它返回时,true因为默认int值是0.
那么有什么方法可以让我理解 Level 属性user2未设置,以便我可以说这两个不相同?
在Python中,我们可以使用@property装饰器来管理对属性的访问。例如,如果我们定义类:
class C:
def __init__(self,value):
self._x = value
@property
def x(self):
"""I'm the 'x' property."""
return self._x
Run Code Online (Sandbox Code Playgroud)
我们可以获取 x 的值,但不能更改它:
c = C(1)
#c.x = 4 # <= this would raise an AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
但是,如果属性是可变类型(例如列表),我们可以为属性的位置设置不同的值:
c = C([0,0])
c.x[0] = 1 # <= this works
Run Code Online (Sandbox Code Playgroud)
有办法预防吗?如果 x 是一个列表,我希望能够仅使用 C 类的方法来更改 x 位置的值。
例如在 PHP 中,
$key1 = 'name';
$key2 = 'mobile';
$person = new Person();
$person->{$key1} = 'Ahmad';
$person->{$mobile} = '60148220678';
Run Code Online (Sandbox Code Playgroud)
我如何在 Flutter(Dart 语言)中实现?我试过了
$key1 = 'name';
$key2 = 'mobile';
$person = new Person();
$person->{$key1} = 'Ahmad';
$person->{$mobile} = '60148220678';
Run Code Online (Sandbox Code Playgroud)
但它显示一个错误
我无法理解为什么 getter/setter 方法的名称必须与属性具有相同的名称。
我尝试在这里阅读亚伦·霍尔的答案,但我仍然找不到(或错过了)关于为什么我们必须使用各自名称的解释。
class Car(object):
def __init__(self, color='blue'):
self.color = color
self.current_model = 'Opel'
@property
def model(self, new_model):
return self.current_model
@model.setter
def model(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
# model = model.setter(models) but doing this works
@model.getter
def model(self):
return self.current_model
Run Code Online (Sandbox Code Playgroud)
编辑: 我发现令人困惑的是,如果我将方法重命名为:
@model.setter
def model_new(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
Run Code Online (Sandbox Code Playgroud)
我尝试运行:
audi = Car()
audi.model = 'BMW' # …Run Code Online (Sandbox Code Playgroud) 我与同事讨论我们不应该stream.map()像这里建议的解决方案那样在内部使用 setter - /sf/answers/2476450441/
这个答案有一个评论不鼓励使用map这种方式,但没有给出为什么这是一个坏主意的原因。有人可以提供一个可能的场景,为什么这会中断?
我已经看到一些讨论,人们通过添加或删除项目来讨论集合本身的并发修改,但是使用map仅将一些值设置为数据对象有什么负面影响吗?
setter ×10
getter ×5
properties ×4
python ×3
object ×2
c# ×1
c++ ×1
collections ×1
dart ×1
doctest ×1
equality ×1
executequery ×1
flutter ×1
inheritance ×1
java ×1
java-8 ×1
java-stream ×1
javascript ×1
linq ×1
mutable ×1
mutators ×1
oop ×1
parent-child ×1
python-2.7 ×1
python-3.x ×1
readonly ×1