标签: object-design

std :: mutex vs std :: recursive_mutex作为类成员

我见过有些人讨厌recursive_mutex:

http://www.zaval.org/resources/library/butenhof1.html

但是在考虑如何实现一个线程安全的类(互斥保护)时,我觉得很难证明每个应该受互斥保护的方法都是互斥保护的,并且互斥锁最多被锁定一次.

因此,对于面向对象的设计,应该std::recursive_mutex是默认的并且std::mutex在一般情况下被视为性能优化,除非它仅在一个地方使用(仅保护一个资源)?

为了说清楚,我说的是一个私人非静态互斥体.因此每个类实例只有一个互斥锁.

在每个公共方法的开头:

{
    std::scoped_lock<std::recursive_mutex> sl;
Run Code Online (Sandbox Code Playgroud)

c++ mutex object-design c++11 recursive-mutex

43
推荐指数
3
解决办法
2万
查看次数

如何在编写对象时避免名称冲突

在JavaScript中,您可以使用某种extend函数组合对象.

例如,我可能有一个observable是公开一组公共方法类(get,push,set,increment,get,等)

在这种情况下可观察到的也恰好是一个EventEmitter所以它也公开了一组新的,公共的方法(emit,on,removeListener等)

这两个类都有内部下划线前缀属性,用于存储状态.eventemitter用于_events存储事件处理程序和可观察的用途_state以及_id存储状态和id.

现在,当我使用像这样的对象组合创建模型时

var Model = extend({}, Observable, {
    constructor: function () {
        // Oops, I was supposed to know Observable uses the _state name already
        this._state = { ... }
    },
    someMethod: function () { ... }
})
Run Code Online (Sandbox Code Playgroud)

这会导致问题,因为Observable已经使用了_state内部属性,现在存在名称冲突.

我认为只是"必须知道"哪些对象依赖于mixin的内部属性才能安全地工作.

如何避免混合使用相同内部属性名称的两个对象?

理想情况下,这将通过ES6私有名称解决,但我们还不能这样做,我们无法模仿它们而不会失去性能.除非您能提供没有大的性能损失的ES6名称仿真,否则我对这些解决方案不感兴趣.

另一种方法是使用闭包, …

javascript naming-conventions composition object-design

5
推荐指数
1
解决办法
407
查看次数

传递(在构造函数中)指向包含一个糟糕设计的类的指针,如果是,那么解决方案是什么

经常我会遇到类似的代码

/*initializer list of some class*/:m_member(some_param,/* --> */ *this)
Run Code Online (Sandbox Code Playgroud)

这样做的原因是m_member可以从包含它的类中调用成员函数... aka

//code in class that is m_member instance of

    m_parent->some_function();
Run Code Online (Sandbox Code Playgroud)

我个人不喜欢它,因为我认为它是可怜的设计("亲爱的孩子,你知道你在做什么对你的课程封装"),但我想知道一般这种行为不好,如果是这样,如何避免这种设计.

编辑:请不要把重点放在initalizer列表中,让我们说它是在ctor体内.

c++ object-design

5
推荐指数
1
解决办法
156
查看次数

Python中的@property速度开销

我正在尝试了解Python中@property装饰器的实用程序。具体来说,我使用如下属性设置了一个类:

class A(object):
    def __init__(self, x):
        self._x = x

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, new_x):
        self._x = new_x
Run Code Online (Sandbox Code Playgroud)

而且我还建立了一个没有提供相同功能的属性的类:

class B(object):
    def __init__(self, x):
        self._x = x
Run Code Online (Sandbox Code Playgroud)

我创建每个实例:

a = A(10)
b = B(10)
Run Code Online (Sandbox Code Playgroud)

在iPython中运行%timeit会产生以下结果

%timeit a.x
%timeit b._x
Run Code Online (Sandbox Code Playgroud)

1000000次循环,每循环3:213 ns的最佳时间

10000000次循环,最佳3:每个循环67.9 ns

%timeit a.x = 15
%timeit b._x = 15
Run Code Online (Sandbox Code Playgroud)

1000000个循环,每个循环最好3:257 ns

10000000次循环,每循环3:89.7 ns最佳

显然,如果您要以很高的频率与该对象交谈,则@property和@setter装饰器会逊色。我的问题就是,为什么要使用它?我想听听人们可能拥有的这些装饰器的用例。谢谢。

python performance properties object-design

5
推荐指数
1
解决办法
2464
查看次数

设计ByteArrayOutputStream的公共接口的理由是什么?

在他们的公共API中有许多java标准和第三方库,有写入或读取的方法Stream.一个例子是javax.imageio.ImageIO.write()OutputStream处理过的图像的内容写入其中.另一个例子是iText pdf处理库,它将OutputStream生成的pdf写入其中.第三个例子是AmazonS3 Java API,InputStream它将读取它并在S3存储中创建文件.

当你想要结合其中两个时,问题就会出现问题.例如,我有一个图像BufferedImage,我必须用它ImageIO.write来推动结果OutputStream.但是,正如S3所要求的那样,没有直接的方法将其推送到Amazon S3 InputStream.
有很多方法可以解决这个问题,但这个问题的主题是使用ByteArrayOutputStream.

后面的想法ByteArrayOutputStream是使用一个包含在其中的中间字节数组,Input/Output Stream以便想要写入输出流的人将写入数组并且想要读取的人将读取数组.

我不知道为什么ByteArrayOutputStream不复制它就不允许任何对字节数组的访问,例如,提供一个InputStream可以直接访问它的字节数组.访问它的唯一方法是调用toByteArray(),它将复制内部数组(标准数组).这意味着,在我的图片示例中,我将在内存中拥有三个图像副本:

  • 首先是实际的BufferedImage,
  • 第二是内部arrayOutputStream
  • 第三是由toByteArray()我制作的副本,所以我可以创建 InputStream.

这个设计如何合理?

  • 隐藏实施?提供getInputStream(),实施保持隐藏.
  • 多线程?ByteArrayOutputStream不管怎样都不适合多线程访问,所以这不可能.

此外,ByteArrayOutputStreamApache的commons-io库(具有不同的内部实现)提供了第二种风格.但两者都具有完全相同的公共接口,无法在不复制的情况下访问字节数组.

java io object-design

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