2

我有 3 个视图模型,它们都必须显示一个人的全名。

现在我当然可以在所有 3 个视图模型中复制该GetFullName()功能,但这并不那么枯燥。

但是我在哪里留下计算人员全名的逻辑呢?

  • 我是否使用四个字段创建一个接口(我们计算四个字段的全名)并在所有 3 个视图模型中实现该接口并创建一个接受该接口并返回一个字符串的“PersonH​​elper”类?
  • 创建自己的类是否逻辑太少?
  • 我是否为其中包含逻辑的 3 个视图模型创建了一个基类?(但是如果我想在 API 函数中使用该函数呢?)
  • Helper 是否可以称为 PersonService,因为在过去它是放置在 Person 类本身中的逻辑,但现在我们将数据类与行为分开(所以也许是“PersonBehaviour”?)

这么简单的事情,有这么多的方法来实现它。

我们对此有何看法?

4

4 回答 4

2

我的第一个想法是询问您的视图模型是直接存储用户数据,还是公开包含用户名的类。如果你不是,我可能会将用户名数据重新分解到它自己的类中(连同其他用户数据,如果这对你的应用程序有意义,那么将 FormattedFullName 属性放在该类中。

public class ViewModel1()
{
    public PersonData myPerson {get; set;}
    // other properties
}

public class ViewModel2()
{
    public PersonData myPerson {get; set;}
    // other properties
}

public class PersonData()
{
    public string forename { get; set; }
    public string surname { get; set; }
    public string FormattedFullName 
    { 
        get 
        { 
            return string.Format("{0} {1}", forename, surname); 
        } 
    }
    // other properties
}
于 2012-12-04T15:52:09.673 回答
2

我们有一个“格式化程序”类,它处理格式化某些数据,例如在多行或单行上显示地址行。

我们这样称呼它:Formatter.FormatAddress(address)其中地址是一个模型类实例。您可以使用您的全名轻松应用此类逻辑。


另一种选择是编写自己的 HtmlHelperExtensions 以便您可以执行Html.FormatFullName(Model.FirstName, Model.LastName).

public static IHtmlString FormatFullName(this HtmlHelper helper, params string[] names)
{
    return new MvcHtmlString(helper.Encode(string.Join(" ", names)));
}

将 html 添加到 HtmlHelperExtensions 也不是不好的做法,所以恕我直言。

于 2012-12-04T16:01:39.883 回答
1

在所有三个 ViewModel 的 BaseClass 中怎么样

public string FirstName {get;set;}
public string LastName {get;set;}
public string FullName {get{return String.Format("{0} {1}",FirstName,LastName);}}

使用基类可以让您最大限度地减少所有三个 ViewModel 的代码重复。这也是一个简单的解决方案,易于理解(由未来的开发人员)并且可以快速更改。API 有什么东西会限制这种功能性吗?

于 2012-12-04T15:51:46.133 回答
1

我会让我的 3 个视图模型实现一个通用接口 IFormattablePerson 具有用于计算全名的字段并依赖于 String.Format

这允许通过在自定义格式化程序中添加新的字符串格式来非常方便地扩展显示。

这将导致类似:

视图模型必须实现的通用接口:

public interface IFormattablePerson: IFormattable
{
string FirstName{get;set;}
string LastName{get;set;}
}   

在每个视图模型中,相同的 ToString() 实现永远不会改变

public string ToString(string format, IFormatProvider formatProvider)
{
    if (formatProvider == null)
        return ToString(format, new FormatProviderIFormattablePerson());
    else
        return (formatProvider.GetFormat(typeof(IFormattablePerson)) as ICustomFormatter).Format(format, this, formatProvider);
}

这将 FormatProvider 和 CustomFormatter 用于 IFormattablePerson。然后你只需要在 CustomFormatter 中添加和实现新的格式

public class FormatProviderIFormattablePerson : IFormatProvider
{
    // String.Format calls this method to get an instance of an
    // ICustomFormatter to handle the formatting.
    public object GetFormat(Type service)
    {
        if (service == typeof(IFormattablePerson))
        {
            return new CustomFormatterIFormattablePerson();
        }
        else
        {
            return null;
        }
    }
}

public class CustomFormatterIFormattablePerson : ICustomFormatter
{
    public string Format(string format, object arg, IFormatProvider provider)
    {
        if (string.IsNullOrEmpty(format))
            format = "full";

        if (arg is IFormattablePerson)
        {
            IFormattablePerson t = (IFormattablePerson) arg;
            switch (format)
            {
                case "f": 
                    return t.FirstName;

                case "l": 
                    return t.LastName;

                case "full": 
                default:
                    return string.Format("{0} {1}",
                        t.FirstName,
                        t.LastName).Trim();
            }                   
        }
        if (arg is IFormattable)
            return string.Format(String.Format("{{0:{0}}}",format), arg);
        else
            return arg.ToString();
    }
}
于 2012-12-04T16:17:21.633 回答