GÜNCELLEME: Bu size bu mekanizma ile çözme sorunu tarif edebilir Is the StaticFactory in codecampserver a well known pattern?Codecampserver'da StaticFactory iyi bilinen bir model midir?
cevap
Düzeltme: Lütfen bu cevabın bir düzenlemede tamamen değiştirilmeden önce verildiğini unutmayın. Bundan dolayı, şimdi sadece orijinal olarak belirtilen soruda mevcut olan şeylere atıfta bulunmaktadır. Tüm "sarkan işaretçiler" için af diliyorum. :-)
Kısa cevap: Yayınladığınız kod ile
, ben IFoo<T>
için döküm bir alternatif görmüyorum. Eğer yapmazsanız, derleyici bir uyarı verecektir (makinemde, en azından).
Daha ayrıntılı cevap:
kodunuzu aslında bu şekilde olmak zorunda mı? Daha spesifik olarak, öncelikle söz konusu oyuncuya ihtiyacınız var mı?
var stringFoo = FooFactory.CreateFoo<string>();
Sen (bu durumda string
) şablonu parametresini sağlamak zorunda herhangi bir yöntem argüman elde edilemez açıkça çünkü:
seni az çok bu gibi fabrika yöntemini çağırmak için gidiyoruz varsayalım (bu durumda aslında hiç yoktur). Açıkçası, fabrika yöntemi bir IFoo<string>
döndürecektir. Şimdi
, açıkça çalışma anında türünü belirtmek zorunda olduğundan, sadece de yazabiliriz:
var stringFoo = StringFoo.Create();
ve bu nedenle bu gibi o koşulsuz bariz yapar StringFoo
içinde bir fabrika yöntemine sahip : Bu if
zincir veya FooFactory.CreateFoo<T>
iç switch
blok kodunuzu yapmak size kazandıracak IFoo<T>
uygulamaları çok diğer bu deseni uygulayarak
public class StringFoo : IFoo<string>
{
...
public static StringFoo Create() // or alternatively, return an IFoo<string>
{
return new StringFoo();
}
}
Daha kolay, ve döküm gerekliliğinden kurtulun (ki bununla ilgili endişeleriniz var).
Yanlış anlama, bazı durumlarda birden çok nesne türü 'u destekleyen fabrika yöntemlerinin yararlı olduğunun farkındayım; ama sizin durumunuzda göründüğünden daha fazla sorun yaratıyor.
P.S. .: İlginç bazı IoC kapları bir yönünü bulabilir.Genellikle yapılandırılmaları gerekir ve bu, soyut arayüzler için somut türleri (yani uygulama sınıfları) kaydettiğiniz bir süreci kapsar; (örneğin burada Autofac kullanarak):
var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
Sonra da geç, soyut bir türünde bir nesne örneğini isteyebilir:
using (var container = builder.Build())
{
var stringFoo = container.Resolve<IFoo<string>>();
...
}
Resolve
yöntem ilginç bir parçasıdır. Bunu soyut bir tiple sağlayın ve kayıtlı türleri kullanarak, StringFoo
türünde somut bir nesne döndürür. Ona bak, eğer senden fazla ses gelmiyorsa! :-)
kopyası? Yaklaşmanın daha açık bir yolu var.
Düzenleme
Ve evet, kod kokuyor. Herhangi bir tür için açık bir oda bıraktınız, daha sonra tek bir türe geri kısıtlama ve bir çalışma zamanı istisnası oluşturma dışında. Bu durumda neden bir parametre var?
Hayır, değilim. Genel bir arayüz sağlayan ancak sonuçta sadece belirli bir somut tip oluşturan soyut bir fabrikanın kullanışlılığını anlamıyorum. Tanımladığınız, henüz tanımlamamış olduğunuz bir soruna bir çözümdür. Bu sorunun nasıl çözüleceğine dair önyargılı fikir yerine, bu sorunun ne olduğunu söyleyin ve size daha iyi yardımcı olacağız. –
Vakumda teknoloji genellikle bir problemin aranmasında çözüm üretiyor. Bu mekanizma tarafından ele alınan durumları tanımlamadan, değer yargısı alabileceğiniz hiçbir kriteriniz yoktur. Sorunuz bu yaklaşımın * bazı * problemleri için geçerli bir çözüm olup olmadığını belirlemek için daha fazlaydıysa, bu farklıdır. Ben jenerik olmayan bir jenerik fabrika için kullanım görmüyorum ve böyle kullanıldığında çalışma zamanı istisnaları neden görmüyorum. Süpermarkete gitmedikçe başlamayacak bir araba yapmak gibi. –
Böyle bir şey deneyebiliriz ...
public static class FooFactory
{
private static readonly Dictionary<Type, Type> FooTypesLookup;
static FooFactory()
{
FooTypesLookup = (from type in typeof(FooFactory).Assembly.GetExportedTypes()
let fooInterface =
type.GetInterfaces().FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IFoo<>))
where fooInterface != null
let firstTypeArgument = fooInterface.GetGenericArguments().First()
select new { Type = type, TypeArgument = firstTypeArgument })
.ToDictionary(x => x.TypeArgument, x => x.Type);
}
public static IFoo<T> CreateFoo<T>()
{
var genericArgumentType = typeof(T);
Type closedFooType;
return FooTypesLookup.TryGetValue(genericArgumentType, out closedFooType)
? (IFoo<T>) Activator.CreateInstance(closedFooType)
: null;
}
}
Ya da daha iyisi, favori IoC kapsayıcı (Windsor, yapı haritası, vs) tanıtılması ve orada IFoo uygulamak her türlü kayıt ve Activator.CreateInstance çağrısı yerine gerektiğinde bunları çöz.
Benim amacım Activator.CreateInstance() kullanmamaktı. – Merritt
- 1. Bir süreliğine IDE kullanmamak iyi midir?
- 2. raylar + ataç: Genel "Ek" modeli iyi bir fikir midir?
- 3. yönlendirici-çıkış bilinen bir
- 4. GMM fit en iyi model
- 5. Tercüman, bir tercümanın uygulama dili için iyi bir dil midir?
- 6. RequestAnimationFrame'i bir geridönüş işlevi içinde kullanmak iyi bir fikir midir?
- 7. Bir GUID'den tire kaldırmak iyi bir fikir midir?
- 8. parentsUntil() kullanmanın en iyi işlevi midir? JQuery
- 9. Kısa talimatlar daha iyi performansa sahip midir?
- 10. Java'da iyi bilinen masaüstü yollarını bulmak için basit, çapraz platform?
- 11. Çoklu Proje Ortamında Belirsiz bağımlılıkları önlemek için İyi Bilinen Strateji
- 12. OrientDB'de bilinen bir yolu arama
- 13. Model sınıfımı en iyi nasıl tasarlayabilirim?
- 14. ServiceManager'ı Model Sınıfında kullanmanın en iyi yolu?
- 15. Rendering Bilinen bir hatayla hata oluştu
- 16. Bilinen dönüşüm tip ve
- 17. Bilinen JavaScript Yönergeleri
- 18. T-SQL: Bilinen değerlerin
- 19. C++ 'da bilinen boyutta bir dizi döndürür? Ben bilinen boyutta bir dizide geçebilir
- 20. iPhone: Bilinen bir kablosuz SSID'ye nasıl bağlanır?
- 21. Yöntem adı bilinen bir yöntemden nasıl alınır?
- 22. SFINAE: Bir işlevin derleme zamanı bilinen değeri
- 23. Web Api'de Her Zaman HttpResponseMessage'i Geri Getirmek Daha İyi midir?
- 24. BlackBerry'de Bitmap veya EncodedImage kullanmak daha iyi midir?
- 25. Raylar, model hatalarını kaydedemedi kaydedildi
- 26. 8 bayt uzun çıkış üreten iyi bilinen bir imza (hash) algoritması var mı?
- 27. İyi bir uygulama, paralel küçük bilinen dondurma işlemi için anonim AsyncTask oluşturuyor mu?
- 28. Oluşturduğum uygulamasında bir model
- 29. Bu, bir dizeyi bir veritabanına şifrelemek için iyi bir yöntem midir?
- 30. Fragman bir etkinlik midir? (Android)
"CreateFoo()" yönteminde bir zincir yerine bir anahtar kullanmalıyım. –
ANeves