下面是一篇关于.net框架模式使用的文章.我不确定我是否理解下面摘录中的粗体部分.是否暗示如果更改创建对象的细节,您(可能)更改构造函数参数?
在框架中有许多情况下,您可以获取结构或类的新实例,而无需自己调用其构造函数.System.Convert类包含许多像这样工作的静态方法.例如,要将整数转换为布尔值,可以调用Convert.ToBoolean并传入整数.如果整数为非零,则此方法调用的返回值为新布尔值设置为"true",否则为"false".Convert类为您创建具有正确值的布尔值.其他类型转换方法类似地工作.Int32和Double上的Parse方法将这些对象的新实例设置为仅给定字符串的适当值.
这种创建新对象实例的策略称为工厂模式.您可以要求对象工厂为您创建实例,而不是调用对象的构造函数.这样,工厂类可以隐藏对象创建的复杂性(比如如何从字符串中解析Double).如果你想改变创建对象的细节,你只需要改变工厂本身; 您不必更改调用构造函数的代码中的每个位置.
我没有很多工厂模式的经验,我遇到过一个我认为有必要的情况,但我不确定我是否已经正确实施了模式,我担心它的影响是什么我的单元测试的可读性.
我创建了一个代码片段,它近似(从内存中)我正在工作的场景的本质.我真的很感激,如果有人可以看看它,看看我做了什么似乎是合理的.
这是我需要测试的类:
public class SomeCalculator : ICalculateSomething
{
private readonly IReducerFactory reducerFactory;
private IReducer reducer;
public SomeCalculator(IReducerFactory reducerFactory)
{
this.reducerFactory = reducerFactory;
}
public SomeCalculator() : this(new ReducerFactory()){}
public decimal Calculate(SomeObject so)
{
reducer = reducerFactory.Create(so.CalculationMethod);
decimal calculatedAmount = so.Amount * so.Amount;
return reducer.Reduce(so, calculatedAmount);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是一些基本的界面定义......
public interface ICalculateSomething
{
decimal Calculate(SomeObject so);
}
public interface IReducerFactory
{
IReducer Create(CalculationMethod cm);
}
public interface IReducer
{
decimal Reduce(SomeObject so, decimal amount);
}
Run Code Online (Sandbox Code Playgroud)
这是我创建的工厂.我当前的要求让我添加了一个特定的Reducer MethodAReducer,用于特定场景,这就是为什么我要介绍一个工厂.
public class ReducerFactory …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
class EntityBase (object) :
__entity__ = None
def __init__ (self) :
pass
def entity (name) :
class Entity (EntityBase) :
__entity__ = name
def __init__ (self) :
pass
return Entity
class Smth (entity ("SMTH")) :
def __init__ (self, a, b) :
self.a = a
self.b = b
# added after few comments -->
def factory (tag) :
for entity in EntityBase.__subclasses__ () :
if entity.__entity__ == tag :
return entity.__subclasses__ ()[0]
raise FactoryError (tag, "Unknown entity")
s = factory …Run Code Online (Sandbox Code Playgroud) 想知道它是否善于将依赖注入与工厂模式相结合?我会在运行时创建不同类型的对象并使用它们,DI很好地注入东西,所以可以在工厂构造中注入这样的传递连接字符串或什么?
谢谢.
我有以下课程:
abstract class Transport{
protected String name;
protected Transport(String name){
this.name=name;
}
protected void DoSomething(){
//Creating some instances of the type of the current instance
}
}
class Bike: Transport {
public Bike(String name): base(name){
}
}
class Bus: Transport {
public Bus(String name): base(name){
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是DoSomething在Transport类的方法内创建一些当前实例类型的实例.
我该怎么办呢?
我可以创建一个静态工厂方法,接受我想要创建的子类的名称,然后通过DoSomething使用方法将它传递给方法中的当前实例的类名this.GetType().Name.
但这是最好的方法吗?
非常感谢大家.
我想向我们的项目介绍CDI(Weld),现在手动构建的对象遇到了一些麻烦.
所以我们有一些实现IReport接口的类,它有一个应该注入的字段.因为所有这些类是由产生这是在运行时零ReportFactory一类ReportController.
private Map<String,Object> generateReport(ReportInfo ri, ...) {
// some input validation
IReport report = ReportControllerFactory.getReportInstance( ri.getClassName() );
// ...
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以将@Produces注释与另一个自定义注释一起使用ReportControllerFactory,但是如何在一个方法中使用@Injectfor只能在完成一些验证之后创建的变量?我将如何提交参数?构造时对象是未知的.ri.getClassName()riReportController
非常感谢你!
亲切的问候,塞巴斯蒂安
编辑于2011年7月8日(10:00):
ReportFactory类:
public static IReport getReportInstance( String className ) throws ReportException {
IReport report = null;
try {
Class<?> clazz = Class.forName( className );
report = (IReport) clazz.newInstance();
}
catch ( Exception e ) { … }
return report; …Run Code Online (Sandbox Code Playgroud) 哪种方式使用Factory更好(正确)?
IPacket info = PacketFactory.CreatePacketObject(PacketType.Info, currentUser, DateTime.Now, " disconnected");
Run Code Online (Sandbox Code Playgroud)
或者我应该丢弃PacketFactory中的第二个方法并使用这个方法吗?
IPacket info = PacketFactory.CreatePacketObject(PacketType.Info);
info.CreationTime = DateTime.Now;
info.Creator = currentUser;
info.Data = " disconnected";
Run Code Online (Sandbox Code Playgroud)
或者其他一些?
PacketFactory代码:
public static class PacketFactory
{
public static IPacket CreatePacketObject(PacketType type)
{
IPacket packetToCreate = null;
switch (type)
{
case PacketType.Info:
packetToCreate = new Info();
break;
case PacketType.Log:
packetToCreate = new Log();
break;
case PacketType.Message:
packetToCreate = new Message();
break;
}
return packetToCreate;
}
public static IPacket CreatePacketObject(PacketType type, Client creator, DateTime creationTime, string data) …Run Code Online (Sandbox Code Playgroud) 我想将对象返回从调用更改为constuctor
从
public class A {
public A(){
}
public String sayHello() {
return "hello";
}
public String foo() {
return "foo";
}
}
Run Code Online (Sandbox Code Playgroud)
至
public class AWrapped extends A {
private A wrapped;
public AWrapped() {
super();
}
public AWrapped(A pWrapped) {
wrapped=pWrapped;
}
public String foo() {
return wrapped.foo();
}
public String sayHello {
return "gday mate";
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是更改从通话返回的对象
A a = new A();
a.sayHello() returns "gday mate"
Run Code Online (Sandbox Code Playgroud)
a是AWrapped的一个实例
我知道这通常是通过工厂模式完成的,但我无法访问A的代码或创建新A的代码.并且有1000个地方可以创建A.
似乎Aspectj可能会做到这一点,但我不太了解它,如果AspectJ会做的诀窍如何绕过无限包装我需要知道它是从内部和方面构建的所以它不会再次包装它.
谢谢Jon的帮助
我正在尝试使用Head First Design Pattern学习面向对象的设计模式.这是本书中工厂模式的一个例子,我想在不违反开放封闭原则的情况下添加新的披萨项目.在书中给出的示例代码中,如果我添加新的披萨项类,我需要修改PizzaStore和PizzaOrder类.但我只是想添加新的Pizza Item而不修改其他类.
public class ChicagoPizzaStore extends PizzaStore {
Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new ChicagoStyleCheesePizza();
} else if (item.equals("veggie")) {
return new ChicagoStyleVeggiePizza();
} else if (item.equals("clam")) {
return new ChicagoStyleClamPizza();
}
else return null;
}
Run Code Online (Sandbox Code Playgroud)
}
这个pizzaStore类是创建和订购披萨.
public abstract class PizzaStore {
abstract Pizza createPizza(String item);
public Pizza orderPizza(String type) {
Pizza pizza = createPizza(type);
System.out.println("--- Making a " + pizza.getName() + " ---");
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
Run Code Online (Sandbox Code Playgroud)
}
这是抽象的Pizza课程: …
我正在完成一个教程,我理解正在教授的内容,示例代码的工作原理如上所述.但我错过了一个难题,那就是工厂如何知道使用哪个"创造"....所以我想我不明白所教的一切.
在尝试研究时,我遇到了这篇文章,但由于他们的情况略有不同,因此没有回答我的"它是怎么知道"的问题.
_modelFactory.Create(f)令我感到困惑.
这是正在执行的代码
_modelFactory = new ModelFactory();
...snip....
public IEnumerable<FoodModel> Get(bool includeMeasures = true)
{
IQueryable<Food> query;
if (includeMeasures)
{ query = _repo.GetAllFoodsWithMeasures(); }
else
{ query = _repo.GetAllFoods(); }
var results = query.OrderBy(f => f.Description).Select(f => _modelFactory.Create(f));
return results;
}
Run Code Online (Sandbox Code Playgroud)
在模型工厂中有两个创建
public class ModelFactory
{
public FoodModel Create(Food food)
{
return new FoodModel()
{ ... };
}
public MeasureModel Create(Measure measure)
{
return new MeasureModel()
{ ... };
}
}
Run Code Online (Sandbox Code Playgroud)
是否存在一些隐式关联,因为"查询"属于Food类型而modelFactory表示哦,我将使用FoodModel,因为这是食物的实体表示?
factory-pattern ×10
c# ×4
factory ×3
java ×3
.net ×2
aspectj ×1
cdi ×1
constructor ×1
inheritance ×1
jboss-weld ×1
moq ×1
python ×1
reflection ×1
unit-testing ×1