我在我的数据库模型之上有一个模型,并在我的存储库中映射对象.
然而,显然我是否直接在我的GetUsers中"选择新"或"选择工厂结果"如下所示.我在运行时得到错误,方法CreateFromDbModel没有转换为sql(System.NotSupportedException).
有没有解决的办法?我能以某种方式修补它吗?
想要使用工厂方法的原因是我可能会在其他地方实例化对象,并希望将"映射代码"保存在一个地方......
感谢任何评论,安德斯
public IQueryable<User> GetUsers(bool includeTeams)
{
return from u in _db.sc_Players
where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam))
select UserFactory2.CreateFromDbModel(u);
}
public static User CreateFromDbModel(sc_Player player)
{
return new User
{
Id = player.sc_PlayerID,
FirstName = player.FirstName.Trim(),
LastName = player.LastName.Trim(),
PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(),
LoginName = player.aspnet_User.LoweredUserName,
IsTeam = player.IsTeam,
Email = player.aspnet_User.aspnet_Membership.Email,
Password = player.aspnet_User.aspnet_Membership.Password
};
}
Run Code Online (Sandbox Code Playgroud) 试图找出如何最好地处理以下场景:
假设一个RequestContext依赖于外部服务的类,例如:
public class RequestContext : IRequestContext
{
private readonly ServiceFactory<IWeatherService> _weatherService;
public RequestContext(ServiceFactory<IWeatherService> weatherService, UserLocation location, string query)
{
_weatherService = weatherService;
...
Run Code Online (Sandbox Code Playgroud)
我应该在最终实例化的类中需要什么样的依赖RequestContext?它可能是ServiceFactory<IWeatherService>,但这似乎不对,或者我可以创建一个IRequestContextFactory以下的线:
public class RequestContextFactory : IRequestContextFactory
{
private readonly ServiceFactory<IWeatherService> _weatherService;
public RequestContextFactory(ServiceFactory<IWeatherService> weatherService)
{
_weatherService = weatherService;
}
public RequestContext Create(UserLocation location, string query)
{
return new RequestContext(_weatherService, location, query);
}
}
Run Code Online (Sandbox Code Playgroud)
然后传递IRequestContextFactory构造函数注入.
这似乎是一种很好的方法,但这种方法的问题在于我认为它阻碍了可发现性(开发人员必须了解工厂并实施它,这并不是很明显).
我错过了更好/更可发现的方式吗?
使用php 5.2,我正在尝试使用工厂将服务返回给控制器.我的请求uri的格式为www.mydomain.com/service/method/param1/param2/etc.然后我的控制器将使用uri中发送的令牌调用服务工厂.从我所看到的情况来看,我的工厂有两条主要路线可供选择.
单一方法:
class ServiceFactory {
public static function getInstance($token) {
switch($token) {
case 'location':
return new StaticPageTemplateService('location');
break;
case 'product':
return new DynamicPageTemplateService('product');
break;
case 'user'
return new UserService();
break;
default:
return new StaticPageTemplateService($token);
}
}
}
Run Code Online (Sandbox Code Playgroud)
或多种方法:
class ServiceFactory {
public static function getLocationService() {
return new StaticPageTemplateService('location');
}
public static function getProductService() {
return new DynamicPageTemplateService('product');
}
public static function getUserService() {
return new UserService();
}
public static function getDefaultService($token) {
return new StaticPageTemplateService($token);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,考虑到这一点,我将有一些通用服务,我将传递该令牌(例如,StaticPageTemplateService和DynamicPageTemplateService),它可能会实现另一个工厂方法,就像这样来获取模板,域对象等等.将是特定服务(例如,UserService),它将是该令牌的1:1而不会被重用.因此,对于少量服务而言,这似乎是一种不错的方法(如果不是,请提供建议).但是,随着时间的推移,随着时间的推移和我的网站的增长,我最终会有100种可能性.这似乎不再是一个好方法.我只是开始使用或者是否有其他更适合的设计模式?谢谢. …
我最近一直在阅读有关工厂模式的文章.我试图找出实现它的最佳方法.在C#Agile Principles模式和实践的书中,建议是像这样创建工厂:
public class ShapeFactoryImplementation : ShapeFactory {
public Shape Make(string name) {
if (name.Equals("Circle"))
return new Circle();
else if (name.Equals("Square"))
return new Square();
else
throw new Exception("ShapeFactory cannot create: {0}", name);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是...
public class ShapeFactoryImplementation : ShapeFactory {
public Shape MakeCircle() {
return new Circle();
}
public Shape MakeSquare() {
return new Square();
}
}
Run Code Online (Sandbox Code Playgroud)
请告诉我你的想法是什么?或者可能有更好的方法来实现工厂模式?
我一直在阅读Factory模式,并且发现了一些文章,建议将Factory模式与依赖注入结合使用,以最大限度地提高可重用性和可测试性.虽然我还没有找到这个Factory-DI混合的任何具体例子,但我将尝试给出一些我的解释的代码示例.但是,我的问题是关于这种方法如何提高可测试性.
所以我们有一个Widget班级:
public class Widget {
// blah
}
Run Code Online (Sandbox Code Playgroud)
我们想要包含一个WidgetFactory来控制Widgets 的构造:
public interface WidgetFactory {
public abstract static Widget getWidget();
}
public class StandardWidgetFactory implements WidgetFactory {
@Override
public final static Widget getWidget() {
// Creates normal Widgets
}
}
public class TestWidgetFactory implements WidgetFactory {
@Override
public final static Widget getWidget() {
// Creates test/mock Widgets for unit testing purposes
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这个例子使用的是Spring DI(这是我唯一经验过的API),但是如果我们谈论的是Guice或任何其他的IoC框架并不重要; 这里的想法是,我们现在要在运行时注入 …
java junit unit-testing dependency-injection factory-pattern
我有一个在数据库中排队的作业列表,我需要从数据库中读取并使用线程并行执行它们,我有一个命令类列表来执行每个所有实现公共接口(命令模式)的作业.但是当我从数据库中检索挂起的作业时,我需要为每个作业实例化正确的命令对象(在工厂类中)
ICommand command;
switch (jobCode)
{
case "A":
command = new CommandA();
break;
case "B":
command = new CommandB();
break;
case "C":
command = new CommandC();
break;
}
command.Execute();
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来创建正确的命令对象而不使用上面的大开关语句?或者是否还有其他模式来执行排队的作业?
解决方案:这样解决(基于所选答案).这将执行命令对象的延迟实例化.
public class CommandFactory
{
private readonly IDictionary<string, Func<ICommand>> _commands;
public CommandFactory()
{
_commands = new Dictionary<string, Func<ICommand>>
{
{"A", () => new CommandA()},
{"B", () => new CommandB()},
{"C", () => new CommandC()}
};
}
public ICommand GetCommand(string jobKey)
{
Func<ICommand> command;
_commands.TryGetValue(jobKey.ToUpper(), out command);
return command();
}
} …Run Code Online (Sandbox Code Playgroud) 我们有一个系统,我们用它来向客户收取不同类型的费用.
有多种充电类型,每种充电类型包括不同的充电项目.
下面是我使用工厂方法得出的问题,这个问题是我需要能够根据充电类型将不同的参数传递给每个Calculate函数,我该如何实现?
//product abstract class
public abstract class ChargeItem
{
public abstract List<ChargeResults> Calculate();
}
//Concrete product classes
public class ChargeType1 : ChargeItem
{
public override List<ChargeResults> Calculate()
{
return new List<ChargeResults> { new ChargeResults { CustomerId = 1, ChargeTotal = 10} };
}
}
public class ChargeType2 : ChargeItem
{
public override List<ChargeResults> Calculate()
{
return new List<ChargeResults> { new ChargeResults { CustomerId = 2, ChargeTotal = 20} };
}
}
public class ChargeType3 : ChargeItem
{
public …Run Code Online (Sandbox Code Playgroud) 我想按照温莎的例子创建一个打字的工厂.这是我的工厂界面:
public interface ICustomJsonResultFactory
{
JsonResult Create();
}
Run Code Online (Sandbox Code Playgroud)
在我的global.asax中,我首先添加以下两个工具来设置Windsor容器:
.AddFacility<FactorySupportFacility>()
.AddFacility<TypedFactoryFacility>();
Run Code Online (Sandbox Code Playgroud)
完成后,我注册我的组件:
Component.For<JsonResult>()
.ImplementedBy<CustomJsonResult>()
.LifestyleTransient(),
Component.For<ICustomJsonResultFactory>()
.AsFactory())
Run Code Online (Sandbox Code Playgroud)
我的一个控制器有一个ICustomJsonResultFactory属性.当我尝试解析控制器时,我在日志中得到以下内容:
Castle.Core.DependencyResolution: DEBUG 8 -
Client: DefaultTypedFactoryComponentSelector / ITypedFactoryComponentSelector
Model: Dependency 'getMethodsResolveByName' type 'System.Boolean'
Dependency: True
Castle.Core.DependencyResolution: DEBUG 8 -
Client: DefaultTypedFactoryComponentSelector / ITypedFactoryComponentSelector
Model: Dependency 'fallbackToResolveByTypeIfNameNotFound' type 'System.Boolean'
Dependency: False
Castle.Core.DependencyResolution: DEBUG 8 -
Client: TypedFactoryInterceptor
Model: Dependency 'kernel' type 'Castle.MicroKernel.IKernelInternal'
Dependency: Castle.MicroKernel.DefaultKernel
Castle.Core.DependencyResolution: DEBUG 8 -
Client: TypedFactoryInterceptor
Model: Dependency 'componentSelector' type 'Castle.Facilities.TypedFactory.ITypedFactoryComponentSelector'
Dependency: Castle.Facilities.TypedFactory.DefaultTypedFactoryComponentSelector
A first …Run Code Online (Sandbox Code Playgroud) 我开始研究不同的设计模式,现在我专注于工厂设计模式.我看了一些例子,youtube tuturials和博客,我得到了最多,但我仍然没有得到为什么接口是必要的.
官方定义是:
定义用于创建对象的接口,但让子类决定实例化哪个类.Factory Method允许类将实例化延迟到子类.
因此,界面似乎是工厂设计模式的重要组成部分,但是我发现在主方法中创建集合时实际的唯一原因.如果你不想要它,你可以删除它(看下面的代码,可能的地方),它仍然像计划的那样工作.
using System;
using System.Collections.Generic;
using System.Collections;
namespace FactoryDesignPattern
{
class Program
{
static void Main(string[] args)
{
var FordFiestaFactory = new FordFiestaFactory();
var FordFiesta = FordFiestaFactory.CreateCar("Blue");
Console.WriteLine("Brand: {0} \nModel: {1} \nColor: {2}", FordFiesta.Make, FordFiesta.Model, FordFiesta.Color);
Console.WriteLine();
//Inserted this later. Using a collection requires the Interface to be there.
List<ICreateCars> Cars = new List<ICreateCars>();
Cars.Add(new FordFiestaFactory());
Cars.Add(new BMWX5Factory());
foreach (var Car in Cars)
{
var ProductCar = Car.CreateCar("Red");
Console.WriteLine("Brand: {0} \nModel: {1} \nColor: {2}", ProductCar.Make, …Run Code Online (Sandbox Code Playgroud) 我正在重构相当大部分的意大利面条代码.简而言之,它是一个很大的"上帝之类"类,根据某些条件分为两个不同的过程.这两个过程都很冗长,并且有很多重复的代码.
所以我的第一个努力就是将这两个进程提取到他们自己的类中,并将公共代码放在他们都继承的父代中.
它看起来像这样:
public class ExportProcess
{
public ExportClass(IExportDataProvider dataProvider, IExporterFactory exporterFactory)
{
_dataProvider = dataProvider;
_exporterFactory = exporterFactory;
}
public void DoExport(SomeDataStructure someDataStructure)
{
_dataProvider.Load(someDataStructure.Id);
var exporter = _exporterFactory.Create(_dataProvider, someDataStructure);
exporter.Export();
}
}
Run Code Online (Sandbox Code Playgroud)
我是Mark Seemann博客的狂热读者,在这篇文章中他解释说这段代码具有时间耦合气味,因为在数据提供程序处于可用状态之前必须调用Load方法.
基于此,并且由于对象被注入到工厂返回的对象中,我正在考虑更改工厂来执行此操作:
public IExporter Create(IExportDataProvider dataProvider, SomeDataStructure someDataStructure)
{
dataProvider.Load(someDataStructure.Id);
if(dataProvider.IsNewExport)
{
return new NewExportExporter(dataProvider, someDataStructure);
}
return new UpdateExportExporter(dataProvider, someDataStructure);
}
Run Code Online (Sandbox Code Playgroud)
由于名称"DataProvider",您可能猜到Load方法实际上正在进行数据库访问.
有些东西告诉我在抽象工厂的create方法中进行数据库访问的对象不是一个好的设计.
是否有任何指导方针,最佳做法或某些事情表明这实际上是一个坏主意?
谢谢你的帮助.
factory-pattern ×10
c# ×6
factory ×2
java ×1
junit ×1
linq-to-sql ×1
oop ×1
php ×1
refactoring ×1
unit-testing ×1