动机:
在阅读Mark Seemann关于Code Smell:Automatic Property的博客时,他说接近结尾:
底线是自动属性很少适用.实际上,只有当属性的类型是值类型并且允许所有可想到的值时,它们才适用.
他给出int Temperature了一个难闻的气味的例子,并建议最好的修复是单位特定值类型,如摄氏.所以我决定尝试编写一个自定义的Celsius值类型,它封装了所有边界检查和类型转换逻辑,作为更加SOLID的练习.
基本要求:
执行:
[System.Diagnostics.DebuggerDisplay("{m_value}")]
public struct Celsius // : IComparable, IFormattable, etc...
{
private int m_value;
public static readonly Celsius MinValue = new Celsius() { m_value = -273 }; // absolute zero
public static readonly Celsius MaxValue = new Celsius() { m_value = int.MaxValue };
private Celsius(int temp)
{
if (temp < Celsius.MinValue)
throw new ArgumentOutOfRangeException("temp", "Value cannot be less then Celsius.MinValue (absolute …Run Code Online (Sandbox Code Playgroud) c# encapsulation design-patterns value-type solid-principles
public class Demo
{
private List<string> _items;
private List<string> Items
{
get
{
if (_items == null)
_items = ExpensiveOperation();
return _items;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Demo该类中的其他方法将可以访问该_items字段.由于我使用属性来延迟加载项目,我不希望其他开发人员错误地尝试使用该_items字段.
我知道我可以使用的是ObsoleteAttribute,但是这个领域在技术上并不过时.
有没有更好的方法将会员标记为"不使用"?
这是基本问题,但我仍然不理解封装概念.我不明白如何从其他类更改类的属性.因为每当我们尝试设置类的公共实例值时,我们必须创建该类的对象然后设置值.每个对象引用不同的内存即使我们更改实例值,这也不会影响任何其他对象.
即使我尝试使用静态公共实例值进行更改,我也无法更改类属性值.
实例如下
// Employee class
public class Employee {
public static int empid;
public static String empname;
public static void main(String[] args) {
System.out.println("print employe details:"+empid+" "+empname);
}
// EmployeeTest class
public class EmployeeTest {
public static void main(String[] args) {
Employee e = new Employee();
e.empid=20;
e.empname="jerry";
Employee.empid=10;
Employee.empname="tom";
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次我Employee上课,我都会得到相同的价值
print employe details:0 null
即使我没有遵循封装概念,我也无法改变员工类的公共实例值.请帮助我理解我出错的概念.
经过几年跟随我工作地点"建筑师"传下来的不良做法并认为必须有更好的方法,我最近一直在阅读TDD和DDD,我认为原则和实践将是一个非常适合我们编写的软件的复杂性.
但是,我见过的许多TDD示例都在域对象上调用一个方法,然后测试对象的属性以确保正确执行行为.
另一方面,业内几位受人尊敬的人(Greg Young最着名的是关于CQRS的讨论)主张通过删除所有"getters"来完全封装每个域对象.
因此,我的问题是:如果禁止检索域状态,如何测试域对象的功能?
我相信我缺少一些基本的东西,所以请随时称我为白痴并启发我 - 任何指导都将非常感谢.
我看到了一个代码,其中getter和setter方法被声明为private.我试图找出它背后的逻辑,我真的很难理解为什么你会将它们声明为私有?这与我们试图通过吸气剂和制定者实现的完全相反.
先期:我很清楚,R是一个功能性的语言,所以请不要咬;-)
我在很多程序中使用OOP方法都有很棒的经验.现在,我想知道在R中使用S4参考类时是否有办法区分公共方法和私有方法?
setRefClass("B",
field=list(
b.1="numeric",
b.2="logical"
),
methods=list(
thisIsPublic=function(...) {
thisIsPublic_ref(.self=.self, ...)
},
thisIsPrivate=function(...) {
thisIsPrivate_ref(.self=.self, ...)
}
)
)
setRefClass("A",
field=list(
a.1="B"
)
)
Run Code Online (Sandbox Code Playgroud)
注意
我通常不会将实际的方法定义放在类def中,而是将其分离为S4方法(即thisIsPublic_ref),原因如下:
x某个类的实例,您可以调用foo_ref(.self=x)而不是x$foo().compiler::cmpfun()如果你有"普通"的引用类方法,它允许你对我认为不可能的方法进行字节编译.对于这个具体的例子来说,确实没那么复杂是有道理的,但我想我会说明这种方法.
setGeneric(
name="thisIsPublic_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPublic_ref")
}
)
setGeneric(
name="thisIsPrivate_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPrivate_ref")
} …Run Code Online (Sandbox Code Playgroud) 面向对象编程的最大优点之一是封装,我们(或者至少,我已经)教过的"真理"之一是成员应该始终保持私密并通过访问者和变异器提供方法,从而确保验证和验证更改的能力.
不过,我很好奇,这在实践中有多重要.特别是,如果你有一个更复杂的成员(例如集合),那么将它公开而不是制作一堆方法来获取集合的密钥,添加/删除集合中的项目是非常诱人的,等等
你一般遵守规则吗?你的答案是否会改变,取决于它是为自己编写的代码还是其他人使用的代码?这种混淆是否有更微妙的原因?
我遇到了不同的采访,问我为什么要使用封装?谁的要求实际上是封装?是程序用户吗?还是同事呢?还是保护代码免受黑客攻击?
我们总是说如果我们简单地定义变量private并定义getter setter来访问这些变量,那么数据将被封装.我的问题是,如果我们可以通过getter和setter访问变量(数据),那么数据是如何隐藏或安全的?
我搜索了大量的解释但没有找到任何东西.每个人都在他们的博客和帖子中说它是一种数据隐藏技术,但没有解释/阐述它.
期待在stackoverflow论坛上获得适当,满意的解释.
我有一个内部可变性的结构.
use std::cell::RefCell;
struct MutableInterior {
hide_me: i32,
vec: Vec<i32>,
}
struct Foo {
//although not used in this particular snippet,
//the motivating problem uses interior mutability
//via RefCell.
interior: RefCell<MutableInterior>,
}
impl Foo {
pub fn get_items(&self) -> &Vec<i32> {
&self.interior.borrow().vec
}
}
fn main() {
let f = Foo {
interior: RefCell::new(MutableInterior {
vec: Vec::new(),
hide_me: 2,
}),
};
let borrowed_f = &f;
let items = borrowed_f.get_items();
}
Run Code Online (Sandbox Code Playgroud)
产生错误:
error[E0597]: borrowed value does not live long enough
--> …Run Code Online (Sandbox Code Playgroud) encapsulation contravariance mutability rust interior-mutability
encapsulation ×10
c# ×3
java ×3
oop ×3
architecture ×1
getter ×1
java-ee ×1
mutability ×1
r ×1
rust ×1
tdd ×1
value-type ×1