[英]How to design this using OOP
我有一个名为User的对象,其中包含Username,Age,Password email等属性。
我在ado.net代码中初始化此对象,如:
private User LoadUser(SqlDataReader reader)
{
User user = new User();
user.ID = (int)reader["userID"];
// etc
}
现在说我创建一个继承自User的新对象,如:
public class UserProfile : User
{
public string Url {get;set;}
}
现在我需要创建一个加载userprofile的方法,所以目前我在做:
public UserProfile LoadUserProfile(SqlDataReader reader)
{
UserProfile profile = new UserProfile();
profile.ID = (int)reader["userID"];
// etc. copying the same code from LoadUser(..)
profile.Url = (string) reader["url"];
}
是否有更多的OOP方法,所以我不必从LoadUser()在LoadUserProfile()镜像我的代码?
我希望我能做到这一点:
UserProfile profile = new UserProfile();
profile = LoadUser(reader);
// and then init my profile related properties
可以这样做吗?
将LodUser方法移动到User Base类并使其成为虚拟。 然后,在UserProfile方法中,您重写此方法。
public class User
{
public virtual void Load(SqlDataReader reader)
{
this.Id = reader["Id"];
//.. whatever else
}
}
public class UserProfile : User
{
public string ExtraProp {get;set;}
public override void Load(SqlDataReader reader)
{
base.Load(reader);
this.ExtraProp = reader["ExtraProp"];
}
}
然后你可以做一些像:
UserProfile up = new UserProfile();
up.Load(myReader);
我真的不明白为什么用户配置文件继承自用户,从逻辑上讲,它没有多大意义。
对我来说有意义的是
public class UserProfile
{
User user;
public string Url {get;set;}
}
然后你可以有类似的东西
public UserProfile LoadUserProfile(SqlDataReader reader)
{
User user = LoadUser(reader);
UserProfile profile = new UserProfile(user);
//load profile stuff from reader...
return profile;
}
首先,为什么你的userprofile继承自用户。 UserProfile不是User。 最糟糕的是,他的遗传继承。
如果您不希望User和UserProfile对象知道SQL(persistence ignorance = good),您可以使用对现有对象进行操作的静态/扩展方法:
private static User LoadFromReader(this User user, SqlDataReader reader)
{
user.ID = (int)reader["userID"];
// etc
return user;
}
public UserProfile LoadFromReader(this UserProfile profile, SqlDataReader reader)
{
((User)profile).LoadFromReader(reader);
profile.Url = (string) reader["url"];
// etc
return profile;
}
然后调用代码可能如下所示:
UserProfile profile = new UserProfile().LoadFromReader(reader);
我会把它改成:
class User
{
public User(SqlDataReader reader)
{
Initialize(reader);
}
protected virtual void Initialize(SqlDataReader reader)
{
this.ID = (int)reader["userID"];
// etc
}
}
class UserProfile : User
{
public UserProfile(SqlDataReader reader) : base(reader) {}
protected override void Initialize(SqlDataReader reader)
{
base.Initialize(reader); // Initialize "user" variables
this.MyProperty = (int)reader["myProperty"];
}
}
这样,每个类初始化自己的值(从构造函数处理),并且只在一个地方有代码。
我会去这里的工厂课。 它会将事情分开来解决单一责任原则 :。 我的答案也是基于User
的构建属性都可以从UserProfile
访问。 UserProfile
的构造函数可以接受User
并获取其所有属性。
public static class UserFactory
{
public static User LoadUser(SqlDataReader reader)
{
int id = (int)reader["userID"];
return new User(id);
}
public static UserProfile LoadUserProfile(SqlDataReader reader)
{
User user = LoadUser(reader);
// extra properties
string url = (string)reader["url"];
return new UserProfile(user, url);
}
}
使LoadUser
虚拟和公共的。 在UserProfile
覆盖它。
简单的答案是覆盖LoadUser函数并在UserProfile类的覆盖函数定义顶部调用base.LoadUser(reader),然后根据UserProfile类的需要获取其余数据。
作为一般规则,此设置不应使用继承,而应使用聚合。 然而,为了说明这一点,它将会这样做。
制作一个带读者的构造函数:
public User(DbDataReader reader) {
ID = reader.GetInt32(reader.GetOrdinal("userID"));
// etc
}
用法:
User adam = new User(reader);
然后你可以让UserProfile中的构造函数调用基础构造函数:
public UserProfile(DbDataReader reader) : base(reader) {
Url = reader.GetString(reader.GetOrdinal("url"));
}
我希望用户配置文件是用户类的成员
public class User
{
//...all current members of the user class...
UserProfile profile;
}
public class UserProfile
{
public string Url {get;set;}
}
除此之外,我会按照Reed Copsey的回答做一些事情
它听起来像你想要做的事情如下:
public class User { public Guid Id { get; set; } }
public class UserProfile : User { public string Url { get; set; } }
class MyReader
{
private T LoadUser<T>(IDataReader reader)
where T : User, new()
{
T user = new T();
user.Id = reader.GetGuid(reader.GetOrdinal("userID"));
return user;
}
public UserProfile LoadUserProfile(IDataReader reader)
{
UserProfile profile = LoadUser<UserProfile>(reader);
profile.Url = (string)reader["url"];
return profile;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.