这是我一直用于工厂的基本模式的示例,它返回一个线程安全的Singleton:
public class UserServiceFactory {
private volatile static UserService userService;
private UserServiceFactory() { }
public static UserService getInstance() {
if (userService == null) {
synchronized(UserServiceImpl.class) {
if (userService == null) {
userService = new UserServiceImpl();
}
}
}
return userService;
}
}
Run Code Online (Sandbox Code Playgroud)
它使用volatile和double check惯用法来确保创建单个实例并在线程中可见.
是否有更简洁和/或更便宜的方式来实现1.6+中的相同目标.
我知道之前已经问过这个问题,但我还没有看到一个简短明了的答案,所以我希望他们不会删除这个问题,现在我会得到一个明确的答案:
我目前在C#5.0工作; .NET 4.5; VS 2012.虽然我已经做了大量的C#,但我主要是一名德尔福人.
在Delphi中,我已经编写了数百个使用以下设计的类工厂(这里很简单):
unit uFactory;
interface
type
TClassofMyClass = class of TMyClass;
TFactoryDict = TDictionary<TMyEnum, TClassofMyClass>;
var fDict:TFactoryDict;
implementation
procedure initDict;
begin
fDict:=TFactoryDict.create;
fDict.add(myEnum1, TMyClass1);
fDict.add(myEnum2, TMyClass2);
fDict.add(myEnum3, TMyClass3);
end;
function Factory(const aEnum: TMyEnum): TMyClass;
var
ClassofMyClass: TClassofMyClass;
begin
if fDict.TryGetValue(aEnum, ClassofMyClass) then
result := ClassofMyClass.Create(aParam);
end;
end.
Run Code Online (Sandbox Code Playgroud)
现在:我如何在C#中做这样的事情?!似乎C#中没有 '类'类型.我错过了什么吗?如何在C#中简单而优雅地实现这种类型的工厂?这个设计也可以在Python中实现 - 为什么C#会更糟??
我需要我的Spring应用程序上下文包含一个bean(Java 7)Path对象,它具有固定的(已知的)路径名.我应该使用什么XML bean定义?
这种豆有一些复杂性:
Path是一个接口,Path应该使用Paths.get(String...)静态工厂方法创建对象.Paths.get(URI).由于对象是-A Path,将class豆的应该是Path:
<bean name="myPath" class="java.nio.file.Path"/>
Run Code Online (Sandbox Code Playgroud)
我需要指出要使用的静态工厂方法,这似乎需要一个factory-method属性.但是工厂方法属于java.nio.file.Paths类而不是java.nio.file.Path类,所以我假设以下方法不起作用:
<bean name="myPath" class="java.nio.file.Path"
factory-method="java.nio.file.Paths.get"/>
Run Code Online (Sandbox Code Playgroud)
最后,我需要给出工厂方法的参数.我怎么做?使用嵌套constructor-arg(sic)元素?那么,这样的事情呢?
<bean name="myPath" class="java.nio.file.Path"
factory-method="java.nio.file.Paths.get">
<constructor-arg value="/my/path/name"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
但这不起作用:Springs抛出一个BeanCreationException,抱怨"找不到匹配的工厂方法:工厂方法'java.nio.file.Paths.get()'."
我刚刚开始使用IoC容器,如果这是一个愚蠢的问题,请道歉.
我在应用程序中有如下代码
internal static class StaticDataHandlerFactory
{
public static IStaticDataHandler CreateHandler(StaticDataUpdate staticDataUpdate)
{
if (staticDataUpdate.Item is StaticDataUpdateOffice)
{
return new OfficeUpdateHandler();
}
if (staticDataUpdate.Item is StaticDataUpdateEmployee)
{
return new EmployeeUpdateHandler();
}
if (staticDataUpdate.Item == null)
{
throw new NotImplementedException(
string.Format("No static data provided"));
}
else
{
throw new NotImplementedException(
string.Format("Unimplemented static data type of {0}", staticDataUpdate.Item.GetType().FullName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
它基本上是一个简单的工厂,它返回处理输入数据的正确策略.
IoC容器是否允许我删除这样的代码?也就是说:它是否允许我根据输入参数的类型动态选择要加载的具体实现?
还是我离开这里?
处理需要在运行时只知道数据的对象时,例如用户名和密码,应该在哪里进行对象实例化:使用new,在工厂或在DI容器中?
例如,new一旦有了数据,我就可以只是一个对象:
UserCredentials creds =
new UserCredentials(dialog.getUsername(), dialog.getPassword());
Run Code Online (Sandbox Code Playgroud)
或者,我可以使用工厂:
UserCredentials creds =
CredentialsFactory.create(dialog.getUsername(), dialog.getPassword());
Run Code Online (Sandbox Code Playgroud)
或者,我可以在DI容器中使用提供程序(在这种情况下,它基本上是一个参数驱动的工厂).[省略示例代码.]
将DI容器用于如此简单的事情似乎都是错误的,但如果不充分利用它也似乎是错误的.
在建造以下工厂时:
Factory.define :user do |f|
f.sequence(:name) { |n| "foo#{n}" }
f.resume_type_id { ResumeType.first.id }
end
Run Code Online (Sandbox Code Playgroud)
ResumeType.first返回nil,我收到一个错误.
ResumeType记录通过夹具加载.我使用控制台检查并且条目在那里,表不是空的.
我在factory_girl邮件列表中找到了一个类似的例子,它应该有效.
我错过了什么?在运行测试之前,我是否必须以某种方式告诉factory_girl设置灯具?
这就是我的test_helper的样子:
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'test_help'
class ActiveSupport::TestCase
self.use_transactional_fixtures = true
self.use_instantiated_fixtures = false
fixtures :all
end
Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用angular-bootstrap-colorpicker,我遇到了一个奇怪的问题.colorpicker模块有一个名为的工厂Slider.这导致颜色选择器无法工作,因为我的应用程序也有一个名为的工厂Slider.不可能在应用程序中重构每一次这样的事情,无论如何它似乎是一个草率的解决方法.抛出的错误是
未捕获的TypeError:Slider.setSaturation不是函数
我得出的结论是因为我的应用程序的工厂没有方法setSaturation而Angular被"混淆"了.我对工厂以及Angular如何组织它们并不是很了解,但似乎很奇怪它们可以在这样的模块之间使用.例如
angular.module('thomasApp', [])
...
.factory('Slider', ...
Run Code Online (Sandbox Code Playgroud)
受到影响
angular.module('colorpicker.module', [])
...
.factory('Slider', ...
Run Code Online (Sandbox Code Playgroud)
或相反亦然.
有没有我可以划分这个颜色选择器,以便它不会干扰我的Slider工厂?
我同意链接的答案,即使用前缀作为命名空间是一个聪明的主意.然而,这将需要不切实际的重构量.我很欣赏下面的答案,但它并没有足够的充实让我能够付诸行动.
1)这真的是最好的解决方案(除了项目开头的前缀)吗? - 如果我做这样的改变,下次我做凉亭更新时会删除它,还是有人拉下我的项目并安装了凉亭?
2)有更好的方法吗? - 如果没有,是否可以扩展当前的答案并解释发生了什么?
所以我在服务器中有一组对象,我想在页面加载时填充ng-repeat.
我有一个工厂从服务器上的资源中获取列表,如下所示:
app.factory('objectArray', ['$http', function($http) {
// This is returning a $$state object
// instead of response.data...
return $http.post('/get_collection').then(function(response) {
console.log(response.data);
return response.data;
});
}]);
Run Code Online (Sandbox Code Playgroud)
在使用ui-router和state声明中的resolve属性之前,我已经有了这段代码.但是当将这个工厂直接注入我的控制器时,而不是获得response.data我得到一个$$状态对象.
我的控制器看起来像这样:
app.controller('applicationController', ['$scope', 'objectArray', function($scope, objectArray) {
$scope.array = objectArray;
console.log($scope.array);
}]);
Run Code Online (Sandbox Code Playgroud) 当Django模型中的字段具有选项选项时,请参阅Django选项字段选项,它使用包含2个项目的可迭代的迭代来定义允许的值.例如:
楷模
class IceCreamProduct(models.Model):
PRODUCT_TYPES = (
(0, 'Soft Ice Cream'),
(1, 'Hard Ice Cream'),
(2, 'Light Ice Cream'),
(3, 'French Ice Cream'),
(4, 'Italian-style Gelato'),
(5, 'Frozen Dairy Dessert'),
)
type = models.PositiveSmallIntegerField('Type', choices=PRODUCT_TYPES, default=0)
Run Code Online (Sandbox Code Playgroud)
要在Factory Boy中生成随机值以供选择,我将使用factory.fuzzy.FuzzyChoice,但这只选择2个项目的可迭代.它不能采用所选迭代的第一项.例如:
工厂
class IceCreamProductFactory(factory.django.DjangoModelFactory):
class Meta:
model = IceCreamProduct
type = factory.fuzzy.FuzzyChoice(IceCreamProduct.PRODUCT_TYPES)
Run Code Online (Sandbox Code Playgroud)
错误
TypeError: int() argument must be a string, a bytes-like object or a number, not 'tuple'
Run Code Online (Sandbox Code Playgroud)
获取元组的第一项是不可能的.例如:
工厂
class IceCreamProductFactory(factory.django.DjangoModelFactory):
class Meta:
model = IceCreamProduct
type = factory.fuzzy.FuzzyChoice(IceCreamProduct.PRODUCT_TYPES)[0]
Run Code Online (Sandbox Code Playgroud)
错误 …
所以我有一个Question像下面这样的课程:
@JsonSerializable()
class Question {
String id;
String content;
Question({this.id, this.content});
factory Question.fromJson(Map<String, dynamic> json) =>
_$QuestionFromJson(json);
Map<String, dynamic> toJson() => _$QuestionToJson(this);
}
Run Code Online (Sandbox Code Playgroud)
请记住,那些_$QuestionFromJson和 _$QuestionToJson来自这个库https://pub.dev/packages/json_serializable
假设我有很多类似的类,它们有一个 fromJson 工厂和一个 toJson 方法。我想创建一个包含这两种方法的基类。基本模型对于 toJson 来说很容易,如下所示:
abstract class BaseModel {
Map<String, dynamic> toJson();
}
Run Code Online (Sandbox Code Playgroud)
但是工厂方法呢,我不知道如何声明它们然后简单地像这样覆盖它:
@override
factory Question.fromJson(Map<String, dynamic> json) =>
_$QuestionFromJson(json);
Run Code Online (Sandbox Code Playgroud)
编辑:
我使用它的想法是因为我想创建一个转换器实用程序,我只需要传递像Converter.listFromJson<MyClass>(jsonString). 现在,助手是:
static List<T> listFromJson<T>(jsonString, Function mappingFunction) {
return myJsonMap.map(mappingFunction).cast<T>().toList();
}
Run Code Online (Sandbox Code Playgroud)
所以我每次使用这个辅助方法时都必须通过传递 map 函数来映射每个项目:
Converter.listFromJson<Question>(
jsonMap, (item) => Question.fromJson(item));
Run Code Online (Sandbox Code Playgroud)
还有一些类需要像这样转换为列表。我想重用没有(item) => Question.fromJson(item) …
factory ×10
angularjs ×2
c# ×2
java ×2
.net ×1
abstract ×1
color-picker ×1
dart ×1
delphi ×1
django ×1
factory-bot ×1
factory-boy ×1
fixtures ×1
flutter ×1
javascript ×1
new-operator ×1
oop ×1
python ×1
singleton ×1
spring ×1
state ×1
unit-testing ×1