我有一个用户实体:
use Doctrine\ORM\Mapping as ORM;
/**
* ExampleBundle\Entity\User
*
* @ORM\Entity()
*/
class User
{
// ...
/**
* @ORM\Column(type="service_expires_at", type="date", nullable=true)
*/
private $service_expires_at;
public function getServiceExpiresAt()
{
return $this->service_expires_at;
}
public function setServiceExpiresAt(\DateTime $service_expires_at)
{
$this->service_expires_at = $service_expires_at;
}
}
Run Code Online (Sandbox Code Playgroud)
当我将用户更新service_expires_at为以下内容时,更新后的service_expires_at值不会保存回数据库:
$date = $user->getServiceExpiresAt();
var_dump($date->format('Y-m-d')); // 2013-03-08
$date->modify('+10 days');
var_dump($date->format('Y-m-d')); // 2013-03-18
$user->setServiceExpiresAt($date);
$em->persist($user);
$em->flush();
Run Code Online (Sandbox Code Playgroud)
但是,如果我传递一个新DateTime对象service_expires_at,则更新的值将正确保存:
$date = $user->getServiceExpiresAt();
$date->modify('+10 days');
$user->setServiceExpiresAt(new \DateTime($date->format('Y-m-d'));
$em->persist($user);
$em->flush();
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
我目前正在考虑升级中型到大型Java代码库中的日志记录机制.当前使用Debug类上的静态方法记录消息,我建议将其从此切换为SLF4J或commons-logging.
应用程序架构师更喜欢我将依赖性封装在SLF4J上(可能将其包装在前面提到的Debug类中).这样可以更容易地在将来更改日志记录实现.
这对我来说似乎有些过分,因为SLF4J已经在抽象具体的日志记录实现.
是否值得在另一个本土抽象中包装像SLF4J这样的第三方日志抽象?
在下面的代码中,似乎类C无法访问A的构造函数,这是因为虚拟继承所必需的.然而,代码仍然编译和运行.它为什么有效?
class A {};
class B: private virtual A {};
class C: public B {};
int main() {
C c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此外,如果我从A中删除默认构造函数,例如
class A {
public:
A(int) {}
};
class B: private virtual A {
public:
B() : A(3) {}
};
Run Code Online (Sandbox Code Playgroud)
然后
class C: public B {};
Run Code Online (Sandbox Code Playgroud)
会(意外地)编译,但是
class C: public B {
public:
C() {}
};
Run Code Online (Sandbox Code Playgroud)
不会像预期的那样编译.
使用"g ++(GCC)3.4.4(cygming special,gdc 0.12,使用dmd 0.125)编译的代码",但已经验证它与其他编译器的行为相同.
c++ inheritance encapsulation virtual-inheritance private-inheritance
我试图弄清楚Clojure是否可以完全取代我在其他语言中习惯的范例.我不明白的一件事是如何在Clojure中以惯用方式实现封装(通过封装,我指的是使用对该数据进行操作的方法(或其他函数)捆绑数据).
这是OOP的一个用例:
var apple = {
type: "macintosh",
color: "red",
cost: 5
markup: 1.5
getInfo: function () {
return this.color + ' ' + this.type + ' apple';
}
getPrice: function(){
return this.cost * this.markup;
}
}
Run Code Online (Sandbox Code Playgroud)
或类似地:
var person = {
birthdate: '8/30/1980',
firstname: 'leeroy',
middleinitial: 'b',
lastname: 'jenkins',
getAge: function () {
return -(new Date()
- new Date(this.birthdate));
}
getFullFormattedName: function () {
return capitalize(this.firstname+' '+this.middleinitial+' '+this.lastname;
}
}
Run Code Online (Sandbox Code Playgroud)
以这种方式将行为与数据捆绑在一起通常很方便,但是Clojure允许这个问题解决的惯用方法是什么?
只是奇怪的是,当我反思所有类型时,我偶然发现了好奇心来检查其他东西.
为什么System.__ComObject集会的阶级mscorlib.dll(有时?)声称是公开的,而事实上它似乎是非公开的?如果我在一个简单的C#控制台应用程序中运行以下代码:
var t = Type.GetType("System.__ComObject");
Console.WriteLine(t.IsPublic); // "True" ?!
Console.WriteLine(t.IsVisible); // "False"
Run Code Online (Sandbox Code Playgroud)
输出似乎有冲突.非嵌套类型(t.IsNested为false)应为IsPublic和提供相同的真值IsVisible.当我看到装配时,IL DASM我看到:
.class private auto ansi beforefieldinit System.__ComObject
extends System.MarshalByRefObject
{
} // end of class System.__ComObject
Run Code Online (Sandbox Code Playgroud)
对我来说,它看起来非常像非公开类,这些对应于下面的C#代码:
namespace System
{
// not public
internal class __ComObject : MarshalByRefObject
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
当我比较其他类型的具有类似的名称,System.__Canon以及类似IL改性剂,既IsPublic与IsVisible预期返回false.
有谁知道为什么(和什么时候)Type.GetType("System.__ComObject").IsPublic给出了真实的?
面向对象设计(OOD)结合了数据及其方法.据我所知,这实现了两件好事:它提供了封装(所以我不关心那里有什么数据,只关心我如何得到我想要的值)和语义(它将数据与名称联系起来,以及它方法始终如一地使用数据.
那么OOD的优势在哪里呢?相反,函数式编程将丰富性归因于动词而不是名词,因此封装和语义都是由方法而不是数据结构提供的.
我使用的是一个处于功能末端的系统,并且不断地用于OO的语义和封装.但我可以看到OO的封装可能成为对象灵活扩展的障碍.所以目前,我可以看到语义更强大.
或封装是所有有价值代码的关键?
编辑:我的意思是OO提供的封装类型.changeColor(door,blue)成为door.changeColor(blue).
language-agnostic oop encapsulation functional-programming semantics
我正在制作一个非常简单的类来表示3D空间中的位置.
目前,我只是让用户访问和修改个人X,Y和Z值直接.换句话说,它们是公共成员变量.
template <typename NumericType = double>
struct Position
{
NumericType X, Y, Z;
// Constructors, operators and stuff...
};
Run Code Online (Sandbox Code Playgroud)
这背后的原因是,因为NumericType是一个模板参数,我不能依赖于有一个体面的方法来检查值的理智.(我怎么知道用户不希望用负值表示位置?)因此,添加getter或setter以使接口复杂化是没有意义的,因为简洁直接访问应该受到青睐.
Pos.X = Pos.Y + Pos.Z; // Versus...
Pos.SetX(Pos.GetY() + Pos.GetZ());
Run Code Online (Sandbox Code Playgroud)
这是一个好的例外吗?我的代码的(假设的)未来维护者是否会追捕我并打击我的脸?
我对Python比较陌生,并且努力将语言的特性与我从C++和Java背景中学到的习惯相协调.
我最近的问题与封装有关,特别是Meyer的" Effective C++ " 第23项总结的一个想法:
friend暂时忽略缺少机制,非成员函数也被认为优于Python中的成员函数吗?
一个强制的,asinine的例子:
class Vector(object):
def __init__(self, dX, dY):
self.dX = dX
self.dY = dY
def __str__(self):
return "->(" + str(self.dX) + ", " + str(self.dY) + ")"
def scale(self, scalar):
self.dX *= scalar
self.dY *= scalar
def scale(vector, scalar):
vector.dX *= scalar
vector.dY *= scalar
Run Code Online (Sandbox Code Playgroud)
鉴于v = Vector(10, 20),我们现在可以调用v.scale(2)或scale(v, 2)加倍向量的大小.
考虑到我们在这种情况下使用属性的事实,两个选项中的哪一个 - 如果有的话 - 更好,为什么?
在ES5中,编写此类代码被认为是一种很好的做法:
(function () {
//some magic
})();
Run Code Online (Sandbox Code Playgroud)
但是在使用let关键字创建的ES6变量中没有附加到window对象.
那么,现在是否需要在IIFE中编写我们的代码,或者它仍然有一些我没有听说过的目的?
我的实体类看起来像这样:
public class Student {
private int grade;
// other fields and methods
}
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
List<Student> students = ...;
Run Code Online (Sandbox Code Playgroud)
我如何排序students的grade,考虑到这是一个私人领域?
encapsulation ×10
oop ×4
c++ ×2
java ×2
.net ×1
c# ×1
cil ×1
clojure ×1
doctrine-orm ×1
ecmascript-6 ×1
iife ×1
inheritance ×1
javascript ×1
list ×1
logging ×1
python ×1
reflection ×1
semantics ×1
slf4j ×1
sorting ×1