例如,假设我们有一个可以配置为以正常价格提供门票的票务系统,但是一旦您在事件发生后X
小时内,您就会以不同的价格提供它们(可能是打折或增加)。我们称之为“急促价格”。此外,一旦你在事件发生后Y
小时内,你就会以另一个价格提供它们。我们称之为“紧急价格”。
表示此配置信息的类可能如下所示:
public class RushTicketPolicy {
private int rushHours;
private int emergencyHours;
public RushTicketPolicy(int rushHours, int emergencyHours) {
this.rushHours = rushHours;
this.emergencyHours = emergencyHours;
}
public int RushHours { get { return this.rushHours; } }
public int EmergencyHours { get { return this.emergencyHours; } }
}
我发现很难为这些具有足够表现力和完整性的变量(和属性)提供名称,而无需参考使用它们的代码,也无需额外的推断。
也就是说,没有看到其余代码或了解其业务需求的人应该能够查看变量名并理解:
X
开始,包括在内。Y
开始,包括在内。有哪些名称可以实现这一目标?
答案 0 :(得分:1)
我喜欢这里的冗长:
DiscountThresholdInSeconds
根据您的编辑#1:
如果您有“Ticket”课程,我只会给它一些折扣:
public class Ticket
{
private List <Discount> m_availableDiscounts = new List<Discount>();
private decimal m_basePrice = 0m;
private DateTime m_showTime;
public Ticket(DateTime showTime)
{
m_showTime = showTime;
}
public List<Discount> Discounts
{
get
{
return m_availableDiscounts;
}
}
public decimal BasePrice
{
get
{
return m_basePrice;
}
set
{
m_basePrice = value;
}
}
public DateTime ShowTime
{
get
{
return m_showTime;
}
}
public decimal CalculatePrice(int quantity)
{
//Apply discounts here...
}
}
public class Discount
{
private int m_thresholdInSeconds = 0;
private decimal m_percentOff = 0m;
private decimal m_flatAmountOff = 0m;
public Discount(int thresholdInSeconds, decimal percentOff, decimal flatAmountOff)
{
m_thresholdInSeconds = thresholdInSeconds;
m_percentOff = percentOff;
m_flatAmountOff = flatAmountOff;
}
public int ThresholdInSeconds
{
get
{
return m_thresholdInSeconds;
}
}
public decimal PercentOff
{
get
{
return m_percentOff;
}
}
public decimal FlatAmountOff
{
get
{
return m_flatAmountOff;
}
}
}
根据问题#2编辑#2
您列出的内容与我提供的代码之间的区别在于,您的仅允许两个不同的折扣期,而我的将支持分层模型。如果我们真的在这里讨论门票,那就把它想象成一个时间表:
现在---------------------------------------------- --------------------------- ShowTime中
在此期间的任何时候,您可能已经超过了符合折扣资格的门槛(检查点,边界等)。
------------ | ------现在------------ | -------------- ---- | --------------- | --- | --- ShowTime中
由于ShowTime是此时间线中的稳定信息,因此您需要捕获showtime的“距离”和适用的折扣。 ShowTime的“距离”是越过的阈值。
答案 1 :(得分:1)
public class SalesPeriodStartRule {
private int mHoursBeforeEvent = 0;
public SalesPeriodStartRule(int hoursBeforeEvent) {
mHours = hoursBeforeEvent;
}
public DateTime GetEffectiveDate(DateTime showDate) {
return showDate.AddHours(-mHoursBeforeEvent);
}
}
public class PricingPolicy {
private SalesPeriodStartRule mRushRule;
private SalesPeriodStartRule mEmergencyRule;
public PricingPolicy(SalesPeriodStartRule rushRule, SalesPeriodStartRule emergencyRule) {
mRushRule = rushRule;
mEmergencyRule = emergencyRule;
}
public string GetPriceCategory(DateTime purchaseDate, DateTime showDate) {
if (purchaseDate > mEmergencyRule.GetEffectiveDate(showDate)) {
return "Emergency";
}
else if (purchaseDate > mRushRule.GetEffectiveDate(showDate)) {
return "Rush";
}
else {
return "Standard";
}
}
}
答案 2 :(得分:0)
将其命名为......:D
RushTicketPolicyValidityIntervalLength
好的,该课程已经有部分信息。那么这个怎么样?
ValidityIntervalLength
或类似的东西。
答案 3 :(得分:0)
也许您可以使用fluent interface来提高API的表现力。 请考虑以下事项:
public class Test
{
public string TestPolicies()
{
int year = 2010;
int month = 11;
int day = 3;
int hour = 15;
int minute = 30;
int second = 0;
DateTime eventDateTime = new DateTime(year, month, day, hour, minute, second);
IConfiguredTicketPolicy emergencyTicketPolicy = new TicketPolicy().Starts(2).HoursBefore(eventDateTime).Inclusive();
IConfiguredTicketPolicy rushTicketPolicy = new TicketPolicy().Starts(4).HoursBefore(eventDateTime).Inclusive();
DateTime now = DateTime.Now;
if (emergencyTicketPolicy.IsEffectiveAsOf(now))
{
return "Emergency";
}
else if (rushTicketPolicy.IsEffectiveAsOf(now))
{
return "Rush";
}
else
{
return "Standard";
}
}
}
TicketPolicy类的实现如下所示:
public class TicketPolicy : IConfigurePolicySalesStart, IConfigurePolicyHoursBefore, IConfigurePolicyInclusive, IConfiguredTicketPolicy
{
private int mHours;
public IConfigurePolicyHoursBefore Starts(int hours)
{
TicketPolicy clone = this.Clone();
clone.mHours = hours;
return clone;
}
private DateTime mEventDateTime;
public IConfigurePolicyInclusive HoursBefore(DateTime eventDateTime)
{
TicketPolicy clone = this.Clone();
clone.mEventDateTime = eventDateTime;
return clone;
}
private bool mInclusive = false;
public IConfiguredTicketPolicy Inclusive()
{
TicketPolicy clone = this.Clone();
clone.mInclusive = true;
return clone;
}
public bool IsEffectiveAsOf(DateTime now)
{
DateTime effectiveDate = mEventDateTime.AddHours(-1*this.mHours);
if (!this.mInclusive)
{
effectiveDate = effectiveDate.AddTicks(1);
}
return effectiveDate.CompareTo(now) < 0;
}
public TicketPolicy Clone()
{
TicketPolicy clone = new TicketPolicy();
clone.Starts(this.mHours);
clone.HoursBefore(this.mEventDateTime);
if (this.mInclusive)
{
clone.Inclusive();
}
return clone;
}
}
接口用于帮助智能感知通过API导航用户,可能没有必要。他们可能看起来像这样:
public interface IConfigurePolicySalesStart
{
IConfigurePolicyHoursBefore Starts(int hours);
}
public interface IConfigurePolicyHoursBefore
{
IConfigurePolicyInclusive HoursBefore(DateTime eventDateTime);
}
public interface IConfigurePolicyInclusive
{
IConfiguredTicketPolicy Inclusive();
}
public interface IConfiguredTicketPolicy
{
bool IsEffectiveAsOf(DateTime now);
}