Một điều đó là có thể rõ ràng là thiết kế của bạn là hơi thiếu sót. Một chuyển đổi trên loại không phải là điều tốt nhất để làm trong một phương pháp chung mà đánh bại mục đích của nó. Nhưng điều không rõ ràng là mục đích của các lớp học của bạn là gì.
Một số suy đoán:
1) Thấy lớp cặp bạn AskItem
và AskTankTruckAggregate<T>
vv Tôi không nghĩ rằng sau này có được một lớp chung, đó là một lớp rất cụ thể, chặt chẽ cùng với AskItem
. Tôi sẽ thiết kế lại nó như
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem
{
//use reflection to find the type that inherits AbstractAggregate<T>
//instantiate the type
//cast to AbstractAggregate<T> and return
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
Gọi nó thích:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
2) Một cách khác: giao công việc sáng tạo tổng hợp để ListItems của bạn.
public abstract class ListItem //or interface
{
protected abstract object Create();
}
public class AskItem : ListItem { //implement to return AskTankTruckAggregate
}
public class BlogItem : ListItem { //implement to return TankTruckBlogAggregate
}
public class ResourceItem : ListItem { //implement to return ResourcesAggregate
}
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem, new()
{
return (AbstractAggregate<T>)new T().Create();
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
Gọi nó thích:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
3) Hoặc như nhau, nhưng làm cho nó mạnh mẽ hơn một chút đánh máy, với việc sử dụng Generics:
public abstract class ListItem<T> where T : ListItem<T> //or interface
{
protected abstract AbstractAggregate<T> Create();
}
public class AskItem : ListItem<AskItem> { //implement to return AskTankTruckAggregate
}
public class BlogItem : ListItem<BlogItem> { //implement to return TankTruckBlogAggregate
}
public class ResourceItem : ListItem<ResourceItem> { //implement to return ResourcesAggregate
}
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient<T>() where T : ListItem, new()
{
return new T().Create();
}
}
public class AskTankTruckAggregate : AbstractAggregate<AskItem>
{
//not implemented yet
}
public class TankTruckBlogAggregate : AbstractAggregate<BlogItem>
{
//not implemented yet
}
public class ResourcesAggregate : AbstractAggregate<ResourceItem>
{
//not implemented yet
}
Gọi nó như:
AbstractAggregateFactory.GetAggregateClient<AskItem>(); //etc
4) Cuối cùng, có thể khiến loại trả lại ít chung chung hơn? Liên quan đến trường hợp chuyển đổi, tôi không thích nó.
public enum AggregateTypes { TankTruckBlog, AskTankTruck, Resources }
public static class AbstractAggregateFactory
{
public static AbstractAggregate GetAggregateClient(AggregateTypes type)
{
switch (type)
{
case AggregateTypes.AskTankTruck:
return new AskTankTruckAggregate<AskItem>();
case AggregateTypes.TankTruckBlog:
return new TankTruckBlogAggregate<BlogItem>();
case AggregateTypes.Resources:
return new ResourcesAggregate<ResourceItem>();
default:
throw new AggregateDoesNotExistException();
}
}
}
public abstract class AbstractAggregate
{
}
public abstract class AbstractAggregate<T> : AbstractAggregate
{
}
//or change the definition to AskTankTruckAggregate : AbstractAggregate<AskItem>
public class AskTankTruckAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
//or change the definition to TankTruckBlogAggregate : AbstractAggregate<BlogItem>
public class TankTruckBlogAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
//or change the definition to ResourcesAggregate : AbstractAggregate<ResourceItem>
public class ResourcesAggregate<T> : AbstractAggregate<T>
{
//not implemented yet
}
Gọi nó thích:
AbstractAggregateFactory.GetAggregateClient(AggregateTypes.AskTankTruck); //etc
Imo, phương pháp này là tồi tệ hơn so với phương pháp phản xạ. Dễ dàng quên một số kiểm tra enum trong tương lai.
Tất cả, thứ 3 trông đẹp nhất cho đôi mắt của tôi, nhưng lại không biết mục tiêu thiết kế của bạn, rất khó dự đoán. Một vài gợi ý:
Tên nhà máy của bạn nghe tốt hơn như AggregateFactory
. "Tóm tắt" trong nó làm cho nó thêm về thực hiện.
Trong trường hợp bạn cần enum để biểu thị loại, đừng đặt lồng nhau. Các loại công cộng lồng nhau khó gọi hơn. Đưa ra lớp tĩnh gói (như trong phương pháp thứ 5 của tôi).
Đổi tên lớp cơ sở là Aggregate<T>
hoặc . Một lần nữa "Tóm tắt" trong nó làm cho nó thêm về thực hiện, khá vô dụng.
cảm ơn lời giải thích chi tiết. ban đầu tôi đã chọn một câu trả lời khác, nhưng bạn đã thuyết phục tôi. cảm ơn đã giúp đỡ! – apexdodge
np :) - có rất nhiều cách/câu trả lời, chỉ cần giữ cho nó hợp lý (mỗi bit thường có mục đích của nó hoặc không đảm bảo một nơi) và bạn sẽ ổn. Và hãy xem IOC, autofac, bạn sẽ thích điều đó (nhiều hơn Generics :) – NSGaga