此问题涉及旧Java版本的行为和双重检查锁定算法的旧实现
较新的实现使用volatile并依赖于稍微改变的volatile语义,因此它们不会被破坏.
据说,除了long或double字段外,字段赋值总是原子的.
但是,当我读到为什么双重检查锁定被破坏的解释时,它说问题在于赋值操作:
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
// other functions and members...
}
Run Code Online (Sandbox Code Playgroud)
- 线程A注意到该值未初始化,因此它获得锁定并开始初始化该值.
- 由于某些编程语言的语义,允许编译器生成的代码在A完成初始化之前更新共享变量以指向部分构造的对象.
- 线程B注意到共享变量已初始化(或显示),并返回其值.因为线程B认为该值已经初始化,所以它不会获得锁定.如果B在B看到A完成的所有初始化之前使用该对象(因为A尚未完成初始化或者因为对象中的某些初始化值尚未渗透到内存B使用(缓存一致性)) ,该程序可能会崩溃.
(来自http://en.wikipedia.org/wiki/Double-checked_locking).
什么时候可能?是否有可能在64位JVM分配操作中不是原子的?如果不是那么"双重检查锁定"是否真的被打破了?
我经常看到并使用带有附加属性的枚举来做一些基本的事情,比如提供显示名称或描述:
public enum Movement {
[DisplayName("Turned Right")]
TurnedRight,
[DisplayName("Turned Left")]
[Description("Execute 90 degree turn to the left")]
TurnedLeft,
// ...
}
Run Code Online (Sandbox Code Playgroud)
并且有一组扩展方法来支持这些属性:
public static string GetDisplayName(this Movement movement) { ... }
public static Movement GetNextTurn(this Movement movement, ...) { ... }
Run Code Online (Sandbox Code Playgroud)
遵循此模式,可以将其他现有或自定义属性应用于字段以执行其他操作.它几乎就像枚举可以作为简单的枚举值类型一样工作,也可以作为一个包含许多字段的更丰富的不可变值对象:
public class Movement
{
public int Value { get; set; } // i.e. the type backing the enum
public string DisplayName { get; set; }
public string Description { get; set; }
public Movement GetNextTurn(...) { ... } …Run Code Online (Sandbox Code Playgroud) 我想明确这一点.当我说域贫血时,我指的是故意的域贫血,而不是偶然的.在我们大多数业务逻辑隐藏在一堆服务背后的世界中,完整的域模型真的是必要的吗?
这是我自从最近开始研究一个项目的问题,其中"领域"模型实际上是一个持久性模型; 没有域对象包含任何方法,这是一个非常有意的决定.
最初,当我看到一个充满了本质上类型安全的数据容器的库时,我打了个哆嗦,但经过一番思考后,我觉得这个特定的系统没有做太多但基本的CRUD操作,所以也许在这种情况下这是一个不错的选择.我想我的问题是,到目前为止我的经验一直非常关注丰富的域名模型,所以它让我有点兴奋.
域逻辑的其余部分隐藏在一组生成在单独组件中的帮助器,外墙和工厂中.
我很想知道人们对此的看法.显然,重用这些类的考虑因素要简单得多,但实际上是非常有益吗?
我目前的工作谁是客户吓呆了改变,因为"业绩原因"烂未检验的和未维护的代码.很明显,存在许多错误观念,而且理由不被理解,而只是盲目信仰.
我遇到的一个这样的反模式是需要标记尽可能多的类作为密封的内部 ...
*重新编辑:我认为将所有内容标记为内部密封(在C#中)作为过早优化.*
我想知道人们可能意识到或遇到的其他一些性能反模式是什么?
我们的硕士论文项目正在创建一个数据库模式分析器.作为此基础,我们正在努力量化糟糕的数据库设计.
我们的主管负责分析我们选择的真实世界模式,以便我们识别一些/几个设计问题.这些问题将用作架构分析器的起点.
找到一个好的模式有点困难,因为我们不想要一个在所有方面都设计得很好的模式,而是一个更"罕见到中等"的模式.
我们已经安排了以下用于分析的模式:维基媒体,moodle和drupal.不确定每个适合的类别.架构没有必要是开源的.
使用的数据库引擎并不重要,但我们希望专注于SQL服务器,Posgresql和Oracle.
目前,文学将被推迟,因为这项任务应该给我们提供可以在论文中使用的真实世界的例子.即"设计X被我们认为是糟糕的设计,我们的分析仪确定并建议改进",而不是提出人为的例子.
当我们准备好某种工具时,我会更新这篇文章.
我已经多次看到使用return $this; 模式样式的Zend Framework - 从我的观点来看:
Pro:对于在同一个对象上链接许多操作并使代码更短,似乎是非常糟糕的模式样式.
Con:当你看到该对象在方法中返回自己时,代码看起来有点奇怪,这会做其他事情(例如某些属性的setter)
它是真正好的模式实践还是反模式实践?
编辑:好吧,从我这边说它有点太多了"模式",感谢大家指点我正确的方向!
可能重复:
为什么单例对象更面向对象?
为什么Scala对Singleton反模式有语言支持?如果Scala static从Java 继承了该关键字,那么该关键字的合法用例object是什么?
按照我在这个线程中给出的建议[ Ninject UOW模式,用户通过身份验证后的新ConnectionString我现在明白我不应该使用以下行...
var applicationConfiguration =
(IApplicationConfiguration)
DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
Run Code Online (Sandbox Code Playgroud)
......作为服务定位器是一种反模式.
但是在以下过程的情况下,如何实例化实现" IApplicationConfiguration "的具体对象,以便我可以使用该对象获取未知用户角色名称,或者使用它来分配我的原则的" ApplicationConfiguration "属性?
Global.asax中
public class MvcApplication : NinjectHttpApplication
{
/// <summary>
/// Handles the PostAuthenticateRequest event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
String[] roles;
var applicationConfiguration =
(IApplicationConfiguration)
DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
var identity = HttpContext.Current.User.Identity;
if (Request.IsAuthenticated)
{
roles = Roles.GetRolesForUser(identity.Name);
}
else
{
roles …Run Code Online (Sandbox Code Playgroud) c# dependency-injection anti-patterns ninject service-locator
每当有任何与组件相关的异步任务执行并且该组件卸载时,React 通常会发出此警告 -
Can't perform a React state update on an unmounted component This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
我通过互联网找到了一些解决方案,将 isMount 标志(通过将其与 useRef 或 useState 一起使用)用作 true,然后在组件卸载时将其更新为 false。但根据 React 站点使用 isMount 的正确解决方案是一种反模式吗?
https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html
您认为在异常中使用错误代码来指定错误类型是否可以?请看一下这段代码:
public class MyException extends Exception {
public static final String ERROR_CODE_INVALID_NAME = "";
public static final String ERROR_CODE_INVALID_ID = "";
...
private String errorCode;
public MyException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
public String getErrorCode() {
return errorCode;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在这个例子中使用enum而不是字符串会更好,但我实际上关心的是错误代码的概念.你认为这里的例外情况会更好吗?我找不到任何权威来源说异常中的错误代码是反模式.谢谢.
anti-patterns ×10
c# ×2
java ×2
.net ×1
error-code ×1
exception ×1
locking ×1
ninject ×1
object ×1
oop ×1
performance ×1
php ×1
postgresql ×1
reactjs ×1
scala ×1
singleton ×1
soa ×1
sql-server ×1
static ×1
warnings ×1