标签: encapsulation

用于创建简单且高效的值类型的模式

动机:

在阅读Mark Seemann关于Code Smell:Automatic Property的博客时,他说接近结尾:

底线是自动属性很少适用.实际上,只有当属性的类型是值类型并且允许所有可想到的值时,它们才适用.

他给出int Temperature了一个难闻的气味的例子,并建议最好的修复是单位特定值类型,如摄氏.所以我决定尝试编写一个自定义的Celsius值类型,它封装了所有边界检查和类型转换逻辑,作为更加SOLID的练习.

基本要求:

  1. 不可能有无效的价值
  2. 封装转换操作
  3. 有效的应对(相当于替换它的int)
  4. 尽可能直观地使用(尝试int的语义)

执行:

[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

24
推荐指数
2
解决办法
8676
查看次数

C#标记成员为"不使用"

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,但是这个领域在技术上并不过时.

有没有更好的方法将会员标记为"不使用"?

c# encapsulation

24
推荐指数
4
解决办法
3871
查看次数

Java Encapsulation Concept不清楚

这是基本问题,但我仍然不理解封装概念.我不明白如何从其他类更改类的属性.因为每当我们尝试设置类的公共实例值时,我们必须创建该类的对象然后设置值.每个对象引用不同的内存即使我们更改实例值,这也不会影响任何其他对象.

即使我尝试使用静态公共实例值进行更改,我也无法更改类属性值.

实例如下

// 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

即使我没有遵循封装概念,我也无法改变员工类的公共实例值.请帮助我理解我出错的概念.

java encapsulation

24
推荐指数
3
解决办法
4万
查看次数

TDD,DDD和封装

经过几年跟随我工作地点"建筑师"传下来的不良做法并认为必须有更好的方法,我最近一直在阅读TDD和DDD,我认为原则和实践将是一个非常适合我们编写的软件的复杂性.

但是,我见过的许多TDD示例都在域对象上调用一个方法,然后测试对象的属性以确保正确执行行为.

另一方面,业内几位受人尊敬的人(Greg Young最着名的是关于CQRS的讨论)主张通过删除所有"getters"来完全封装每个域对象.

因此,我的问题是:如果禁止检索域状态,如何测试域对象的功能?

我相信我缺少一些基本的东西,所以请随时称我为白痴并启发我 - 任何指导都将非常感谢.

c# tdd getter encapsulation domain-driven-design

23
推荐指数
2
解决办法
2774
查看次数

为什么要声明getter和setter方法是私有的?

我看到了一个代码,其中getter和setter方法被声明为private.我试图找出它背后的逻辑,我真的很难理解为什么你会将它们声明为私有?这与我们试图通过吸气剂和制定者实现的完全相反.

java encapsulation getter-setter

23
推荐指数
2
解决办法
1万
查看次数

有没有办法为S4 Reference Classes声明公共和私有方法?

先期:我清楚,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),原因如下:

  1. 这样,在单个方法defs变得非常大的情况下,类def保持清晰排列并且更容易阅读.
  2. 它允许您随时切换到方法的功能执行.作为x某个类的实例,您可以调用foo_ref(.self=x)而不是x$foo().
  3. 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)

oop encapsulation r private-methods public-method

23
推荐指数
2
解决办法
5322
查看次数

在实践中私人与公共成员(封装有多重要?)

面向对象编程的最大优点之一是封装,我们(或者至少,我已经)教过的"真理"之一是成员应该始终保持私密并通过访问者和变异器提供方法,从而确保验证和验证更改的能力.

不过,我很好奇,这在实践中有多重要.特别是,如果你有一个更复杂的成员(例如集合),那么将它公开而不是制作一堆方法来获取集合的密钥,添加/删除集合中的项目是非常诱人的,等等

你一般遵守规则吗?你的答案是否会改变,取决于它是为自己编写的代码还是其他人使用的代码?这种混淆是否有更微妙的原因?

language-agnostic encapsulation

22
推荐指数
3
解决办法
3359
查看次数

为什么封装是OOP语言的一个重要特性?

我遇到了不同的采访,问我为什么要使用封装?谁的要求实际上是封装?是程序用户吗?还是同事呢?还是保护代码免受黑客攻击?

architecture oop encapsulation software-design

22
推荐指数
5
解决办法
2万
查看次数

Java封装

我们总是说如果我们简单地定义变量private并定义getter setter来访问这些变量,那么数据将被封装.我的问题是,如果我们可以通过getter和setter访问变量(数据),那么数据是如何隐藏或安全的?

我搜索了大量的解释但没有找到任何东西.每个人都在他们的博客和帖子中说它是一种数据隐藏技术,但没有解释/阐述它.

期待在stackoverflow论坛上获得适当,满意的解释.

java oop encapsulation java-ee

21
推荐指数
4
解决办法
1万
查看次数

如何在不破坏封装的情况下返回对RefCell内部内容的引用?

我有一个内部可变性的结构.

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

21
推荐指数
3
解决办法
2487
查看次数