Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
.NetÖеÄAOPϵÁÐÖ®¹¹½¨Ò»¸öÆû³µ×âÁÞÓ¦ÓÃ
 
À´Ô´£ºwww.cnblogs.com ·¢²¼ÓÚ£º 2017-11-9
  4109  次浏览      28
 

±¾ÆªÄ¿Â¼

¿ªÊ¼Ò»¸öÐÂÏîÄ¿

ûÓÐAOPµÄÉú»î

±ä¸üµÄ´ú¼Û

ʹÓÃAOPÖØ¹¹

±¾ÏµÁеÄÔ´Âë±¾ÈËÒÑÍйÜÓÚCodingÉÏ£ºµã»÷²é¿´¡£

±¾ÏµÁеÄʵÑé»·¾³£ºVS 2013 Update 5£¨½¨Òé×îºÃʹÓü¯³ÉÁËNugetµÄVS°æ±¾£¬VS Express°æÒ²¹»Óã©£¬°²×°ÁËPostSharp¡£

ÕâÆª²©¿Í¸²¸ÇµÄÄÚÈݰüÀ¨£º

ΪÏîÄ¿´´½¨ÐèÇó

´ÓÁã±àд´úÂëÀ´Âú×ãÐèÇó

²»Ê¹ÓÃAOPÖØ¹¹ÁèÂҵĴúÂë

ʹÓÃAOPÀ´Öع¹´úÂë

ÕâÒ»½Ú»á¹¹½¨Ò»¸öÆû³µ×âÁÞϵͳ£¬ÏÈÊǸø¶¨ÒµÎñÐèÇó£¬È»ºóÖð½¥µØÌí¼Ó´úÂëÀ´Âú×ãÄÇЩÐèÇó¡£

Ò»¿ªÊ¼²»Ê¹ÓÃÈκÎAOP£¬´ÓÁ㿪ʼÇôúÂë¡£ÒµÎñÐèÇóÊÇ×îÖØÒªµÄ£¬Òò´ËÎÒÃÇÏÈ×öÐèÇó£¬Ò»µ©Âú×ãÁËÒµÎñÂß¼­£¬È»ºóÔÙ¸²¸Ç·Ç¹¦ÄÜÐèÇó¡£×îºó£¬¾¡¿ÉÄܵؼò»¯²¢Öع¹´úÂ룬²»Ê¹ÓÃAOPÀ´Öع¹ºáÇйØ×¢µã¡£

ÕâЩ¶¼Íê³ÉÖ®ºó£¬¾Í»áתÏòÒ»¸öÓ¦ÓÃÉúÃüÖÜÆÚµÄ³¤Î²½×¶Î¡£Èí¼þºÜÉÙÊdz¤ÆÚ²»±äµÄ£ºÐµĹ¦ÄÜÐèÇóºÍз¢ÏÖµÄbugs¡£ºÜÉÙÓÐÈí¼þµÄ¿ª·¢½×¶Î»á±ÈÉú²ú½×¶Î³¤£¬Õâ¾ÍÒâζ×Å´ó¶àÊýÈí¼þµÄÉúÃüÖÜÆÚÊÇά»¤½×¶Î¡£Ò»¸öά»¤À§ÄÑ»ò°º¹óµÄÓ¦ÓûᵼÖ¸ߴú¼Û»òÕßµÍÆ·ÖÊ£¨»òÁ½Õß¶¼ÓУ©£¬×îÖÕÐγÉÒ»¸ö´óÄàÇò¡£

È»ºó£¬»áʹÓÃPostSharpÖØ¹¹´úÂ룬½«¸÷×ԵĺáÇйØ×¢µã·ÖÀëµ½ËüÃÇ×Ô¼ºµÄÀàÖС£Ò»µ©Öع¹Íê³É£¬Äã¾Í»á¿´µ½Ê¹ÓÃAOPµÄºÃ´¦£¬ÌرðÊÇÌí¼Ó¸ü¶à¹¦ÄÜʱ¡£

¿ªÊ¼Ò»¸öÐÂÏîÄ¿

ʱ¼ä£ºÏÖÔÚ

µØµã£ºÄ㹫˾£¨Æû³µ×âÁÞ·þÎñÏà¹Ø£©µÄÑз¢²¿µÄ°ì¹«ÊÒ

ÈËÎÄãµÄ¼¼ÊõÍŶӻòÕßÖ»ÓÐÄã×Ô¼º

±³¾°£ºÆô¶¯Ò»¸öеÄÏîÄ¿£¬¸ß´óÉÏÒ»µã£¬½Ð×ö¿Í»§Öҳ϶Èϵͳ£¬lowÒ»µã£¬½Ð×ö¿Í»§»ý·Ö³ÌÐò¡£Ä¿µÄÊÇΪÁËÔö¼ÓÏúÊÛ£¬½±ÀøÄÇЩ¾­³£¹ºÂò·þÎñµÄ¿Í»§¡£±ÈÈ磬¿Í»§½ñÌì×âÁÞÁËÒ»Á¾³µ£¬ÄÇôËû¾Í»á»ñµÃ»ý·Ö£¬»ý·ÖÀÛ»ý¶àÁËÖ®ºó£¬ÒÔºó¿ÉÒÔÓÃÓÚµÖÏûÒ»²¿·Ö×âÁÞ·ÑÓûòÆäËû·ÑÓá£

¼ÙÉèÓÐÒ»¸ö»ù±¾µÄÈý²ã¼Ü¹¹£¬ÈçÏÂͼ¡£ÎÒÃÇ»á´ÓÓ¦Óõ½Õâ¸ö»ý·ÖϵͳµÄºËÐÄÒµÎñÂß¼­²ã×ÅÊÖ±àд´úÂ룬³Ö¾Ã»¯²ã»á¸ú×Ù¿Í»§µÄÖҳ϶Ȼý·Ö£¬ÒµÎñÂß¼­²ã¹©ËùÓеÄUI²ãʹÓãºÍøÕ¾£¬APPºÍµêԱʹÓõÄ×ÀÃæ¶Ë¡£

Õâһƪ£¬ÎÒÃÇÖ÷Òª¿´Ò»ÏÂÖмäÒ»²ãµÄÒµÎñÂß¼­²ã¡£ÎÒÃÇ¿ÉÒÔ¼ÙÉè³Ö¾Ã»¯²ãÒѾ­ÊµÏÖÁË£¬»¹Òª¼ÙÉèÒ»µ©ÒµÎñÂß¼­ÊµÏÖÁË£¬UIÒ²¾ÍʵÏÖÁË¡£

ÒµÎñÐèÇó

ÏîÄ¿¾­ÀíºÍÀûÒæÏà¹ØÈË£¨±ÈÈçÏúÊÛºÍÊг¡£©È·¶¨ÁËÏÂͼµÄÒµÎñÐèÇó£¬ÄãÒѾ­È·¶¨ÁËÁ½¸öÖ÷ÒªµÄÐèÇ󼯣ºÀÛ»ý»ý·ÖºÍʹÓÃÀÛ»ýµÄ»ý·Ö ¶Ò»»½±Àø¡£

ÏÖÔÚµÄÒµÎñÐèÇó¾ÍÊÇ£º¿Í»§Ã¿×âÒ»ÌìÆÕͨÐͳµÁ¾£¬ÀÛ»ýÒ»»ý·Ö£¬ºÀ»ªÐÍ»òÕß´óÐͳµÁ¾£¬Ã¿ÌìÁ½»ý·Ö¡£ÕâЩ»ý·Ö»áÔÚËûÃÇÖ§¸¶Ö®ºó²¢·µ»¹Á˳µÒÔºó»áÔö¼Óµ½ËûÃǵÄÕË»§ÖС£Ò»µ©¿Í»§ÀÛ»ýÁË10»ý·Ö£¬ÄÇô¾Í¿ÉÒÔʹÓÃÕâЩ»ý·Ö¶Ò»»½±ÀøÁË£¬¾ßÌå¶Ò»»¹æÔò¼ûÉÏͼ¡£

Õâ¾ÍÊÇËùÓÐÒµÎñ¹æÔò£¬µ«ÊÇÔÚʵÏÖ֮ǰ»¹ÊǵúÍÏúÊÛºÍÊг¡È·¶¨ºÃ£ºÒòΪËûÃǽ«À´¿Ï¶¨»¹»á¸ü¸Ä»òÕßÌí¼ÓһЩ¶«Î÷¡£

±ØÒªµÄ·Ç¹¦ÄÜÐèÇó

ÔÚ¸øÏîÄ¿¾­Àí¹ÀËãʱ¼äºÍ»¨Ïú֮ǰ£¬ÄãÓÐ×Ô¼º±ØÐëÒª½â¾öµÄ¼¼Êõ¹Ø×¢µã¡£

µÚÒ»£¬ÐèÒª¼Ç¼ÈÕÖ¾¡£Èç¹û¿Í»§µÄ»ý·ÖÀÛ»ýµÃ²»¶Ô£¨ÀÛ»ýÉÙÁË£©£¬ÄÇôËûÃÇ»áÉúÆøµÄ£¬Òò´Ë±ØÐëÈ·±£¼Ç¼ÁËÒµÎñÂß¼­´¦ÀíµÄÒ»ÇУ¨ÓÈÆäÊÇÆð³õ½×¶Î£©¡£

µÚ¶þ£¬ÒòΪҵÎñÂß¼­´úÂë»á±»¶à¸öUIÓ¦ÓÃʹÓã¬ÒªÈ·±£´«ÈëÒµÎñ²ãµÄÊý¾ÝÊǺϷ¨µÄ£¬ÄãµÄ¶ÓÓÑ¿ÉÄÜ»áÔÚUIÀïдÈëһЩ¼¯³É´úÂ룬Òò´Ë£¬±ØÐë±àд·ÀÓùÐÔ´úÂëÀ´¼ì²éÎÞÒâÒåµÄ±ßÔµÇé¿öºÍ²ÎÊý¡£

µÚÈý£¬»¹ÊÇÒòΪҵÎñÂß¼­´úÂë»á±»¶à¸öUIÓ¦ÓÃʹÓã¬ÕâЩUI¿ÉÄÜ»áʹÓò»Í¬ÀàÐ͵ÄÁ¬½Ó£¨»ºÂýµÄÒÆ¶¯ÊÖ»úµÄÁ¬½Ó£¬¹úÍâä¯ÀÀÆ÷·ÃÎʵȵȣ©£¬ÄãÐèÒª²ÉÓÃÊÂÎñºÍÖØÊÔÂß¼­À´È·±£Î¬»¤Êý¾Ý¼¯³ÉÒÔ¼°¸øÓû§Ìṩһ¸öÓä¿ìµÄÌåÑé¡£

×îºó£¬×ÜÓÐÒâÍâ»á·¢Éú£¬Äã¿ÉÄܲ»ÖªµÀ´ËʱÄã»áʹÓúÎÖÖÀàÐ͵ij־û¯£¬ËùÒÔÐèҪijÖÖ·½·¨´¦ÀíÒì³££¨ºÜ¿ÉÄÜÊǼǼÈÕÖ¾£©¡£

ûÓÐAOPµÄÉú»î

½«ÆÀ¹ÀÌá½»¸øÏîÄ¿¾­ÀíÖ®ºó£¬ËùÓеÄÅú×¼ºÍÎļþÒ²ÒѾ­Ç©ÊðÁË£¬ÏÖÔھͿÉÒÔ¿ªÊ¼ÁË¡£

н¨Ò»¸ö½â¾ö·½°¸£¬Ãû½ÐCarRental£¬²¢´´½¨Ò»¸öÀà¿âÏîÄ¿´æ·ÅÒµÎñÂß¼­£¬È¡ÃûCarRental.Core

±àдҵÎñÂß¼­

´´½¨Ò»¸öÀÛ»ý»ý·ÖµÄ½Ó¿Ú£¬´úÂëÈçÏ£º

public interface ILoyaltyAccrualService
{
void Accrue(RentalAgreement agreement);
}

RentalAgreementÊǸûý·ÖϵͳÁìÓò¹«ÓõÄÒ»¸öʵÌåÀ࣬Òò´Ë°´Àí˵ËüÓ¦¸ÃÔÚÒ»¸ö²»Í¬µÄ³ÌÐò¼¯£¬µ«ÕâÀïΪÁËÑÝʾ£¬ÎÒ´´½¨ÁËÒ»¸öEntitiesµÄÎļþ¼Ð£¬´æ·ÅËùÓеÄʵÌå¡£


public class RentalAgreement
{
public Guid Id { get; set; }
public Customer Customer { get; set; }
public Vehicle Vehicle { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}


public class Customer
{
public Guid Id { get; set; }
public string Name { get; set; }
public string DriversLicense { get; set; }
public DateTime DateOfBirth { get; set; }
}

public class Vehicle
{
public Guid Id { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public Size Size { get; set; }
public string Vin { get; set; }
}

public enum Size
{
Compact=0,
Midsize,
FullSize,
Luxury,
Truck,
SUV
}

ÔÙ»ØÍ·¿´ILoyaltyAccrualService½Ó¿Ú£¬¸Ã½Ó¿ÚÓÐÒ»¸öʹÓÃÁËÕâЩʵÌåµÄAccure·½·¨£¬ÓÃÀ´Îª¿Í»§ÀÛ»ý»ý·Ö¡£ÏÂÃæÊǸýӿڵÄʵÏÖ£¬Ëü»áÒÀÀµÒ»¸ö³Ö¾Ã»¯Êý¾ÝµÄ·þÎñ¡£Accure·½·¨»á°üº¬Á˼ÆËãЭÒéÖÐÌìÊýºÍÕâЩÌì¹²ÀÛ»ý¶àÉÙ»ý·ÖµÄÒµÎñÂß¼­£¬²¢½«ÕâЩ»ý·ÖÊýÁ¿´æ´¢µ½Êý¾Ý¿âÖС£

public class LoyaltyAccrualService :ILoyaltyAccrualService
{
private readonly ILoyaltyDataService _loyaltyDataService;

public LoyaltyAccrualService (ILoyaltyDataService loyaltyDataService)
{
_loyaltyDataService = loyaltyDataService;//Êý¾Ý·þÎñ±ØÐëÔڸöÔÏó³õʼ»¯Ê±´«Èë¸Ã¶ÔÏó
}
/// <summary>
/// ¸Ã·½·¨°üº¬ÁË»ý·ÖϵͳÀÛ»ý¿Í»§»ý·ÖµÄÂß¼­ºÍ¹æÔò
/// </summary>
/// <param name="agreement">×âÁÞЭÒéʵÌå</param>
public void Accrue (RentalAgreement agreement)
{
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = (int)rentalTimeSpan.TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >=Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays*pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id,points);
}
}

ILoyaltyDataServiceÖ»ÓÐÁ½¸ö·½·¨£º

public interface ILoyaltyDataService
{
void AddPoints(Guid customerId,int points);
void SubstractPoints(Guid customerId, int points);
}

ILoyaltyDataService×÷ΪÊý¾Ý¿â½Ó¿Ú£¬»áͨ¹ýDIµÄ·½Ê½´«Èëµ½ÒµÎñ²ãµÄ¹¹Ô캯Êý¡£ÒòΪÎÒÃÇÏÖÔÚÖ»¼¯ÖÐÔÚÒµÎñÂß¼­²ã£¬ËùÒÔÎÒÃÇÔÚÊý¾Ý·þÎñ²ãÖ»ÊǼòµ¥µØ´òӡһЩ¶«Î÷¾ÍºÃÁË£¬FakeLoyaltyDataServiceʵÏÖÁËILoyaltyDataServiceÈçÏ£º

public class FakeLoyalDataService:ILoyaltyDataService
{
public void AddPoints(Guid customerId, int points)
{
Console.WriteLine("¿Í»§{0}Ôö¼ÓÁË{1}»ý·Ö",customerId,points);
}

public void SubstractPoints(Guid customerId, int points)
{
Console.WriteLine("¿Í»§{0}¼õÉÙÁË{1}»ý·Ö", customerId, points);
}
}

µ½ÕâÀÒѾ­Íê³ÉÁËÀÛ»ý»ý·ÖµÄÒµÎñÂß¼­£¡ÏÖÔڻص½¿Í»§¹ØÐĵÄÎÊÌâÉÏ£¬ÈçºÎ¶Ò»»»ý·Ö£¿´´½¨Ò»¸ö½Ó¿ÚILoyaltyRedemptionService£º

public interface ILoyaltyRedemptionService
{
void Redeem(Invoice invoice, int numberOfDays);
}

/// <summary>
/// ·¢Æ±ÊµÌå
/// </summary>
public class Invoice
{
public Guid Id { get; set; }
public Customer Customer { get; set; }
public Vehicle Vehicle { get; set; }
public int CostPerDay { get; set; }
public decimal Discount { get; set; }
}

¶Ò»»»ý·ÖÊÇ»ùÓÚ¿Í»§×âÁ޵ijµÐͺͶһ»µÄÌìÊý´Ó¿Í»§µÄÕË»§ÖмõÈ¥»ý·Ö£¬²¢Ìî³ä·¢Æ±ÖеÄÕÛ¿Û½ð¶î¡£´úÂëÈçÏ£º

public class LoyalRedemptionService: ILoyaltyRedemptionService
{
private readonly ILoyaltyDataService _loyaltyDataService;

public LoyalRedemptionService (ILoyaltyDataService loyaltyDataService)
{
_loyaltyDataService = loyaltyDataService;
}

public void Redeem (Invoice invoice, int numberOfDays)
{
var pointsPerDay = 10;
if (invoice.Vehicle.Size> =Size.Luxury)
{
pointsPerDay = 15;
}
var totalPoints = pointsPerDay*numberOfDays;
invoice.Discount = numberOfDays* invoice.CostPerDay;
_loyaltyDataService.SubstractPoints ( invoice.Customer.Id,totalPoints);
}
}

²âÊÔÒµÎñÂß¼­

ÏÂÃæ´´½¨Ò»¸ö¿ØÖÆÌ¨UIÄ£ÄâÒµÎñÂß¼­µÄʹÓãº

class Program
{
static void Main(string[] args)
{
SimulateAddingPoints();//Ä£ÄâÀÛ»ý
Console.WriteLine("***************");
SimulateRemovingPoints();//Ä£Äâ¶Ò»»
Console.Read();
}

/// <summary>
/// Ä£ÄâÀÛ»ý»ý·Ö
/// </summary>
static void SimulateAddingPoints()
{
var dataService= new FakeLoyalDataService();//ÕâÀïʹÓõÄÊý¾Ý¿â·þÎñÊÇαÔìµÄ
var service= new LoyaltyAccrualService (dataService);
var agreement= new RentalAgreement
{
Customer = new Customer
{
Id = Guid.NewGuid(),
Name = "tkbÖÁ¼ò",
DateOfBirth = new DateTime(2000,1,1),
DriversLicense = "123456"
},
Vehicle = new Vehicle
{
Id = Guid.NewGuid(),
Make = "Ford",
Model = "½ðÅ£×ù",
Size = Size.Compact,
Vin = "Õã-ABC123"
},
StartDate = DateTime.Now.AddDays(-3),
EndDate = DateTime.Now
};
service.Accrue(agreement);
}

/// <summary>
/// Ä£Äâ¶Ò»»»ý·Ö
/// </summary>
static void SimulateRemovingPoints()
{
var dataService = new FakeLoyalDataService();
var service = new LoyalRedemptionService (dataService);
var invoice = new Invoice
{
Customer = new Customer
{
Id = Guid.NewGuid(),
Name = "Farb",
DateOfBirth = new DateTime(1999, 1, 1),
DriversLicense = "abcdef"
},
Vehicle = new Vehicle
{
Id = Guid.NewGuid(),
Make = "°ÂµÏ",
Model = "Q7",
Size = Size.Compact,
Vin = "Õã-DEF123"
},
CostPerDay = 100m,
Id = Guid.NewGuid()
};
service.Redeem(invoice,3);//ÕâÀï¶Ò»»3Ìì
}
}

 

ÔËÐгÌÐò£¬Î±ÔìµÄÊý¾Ý·þÎñ»áÔÚ¿ØÖÆÌ¨ÉÏ´òӡһЩ¶«Î÷£¬½á¹ûÈçÏ£º

ÏÖÔÚ£¬ÒµÎñÂß¼­Íê³ÉÁË£¬´úÂëºÜ¸É¾»£¬·ÖÀëµØÒ²ºÜºÃ£¬ºÜÈÝÒ×ÔĶÁºÍά»¤£¬µ«ÊÇÕâ´úÂ뻹²»ÄܽøÈëÉú²ú»·¾³£¬ÒòΪÓи÷ÖÖ¸÷Ñù¿ÉÄÜ»á³ö´íµÄÊÂÇé·¢Éú£¬Òò´ËÏÂÃæ×ÅÊÖй¦ÄܵÄÐèÇ󿪷¢¡£

Ìí¼ÓÈÕÖ¾

ËäÈ»É󼯻ý·ÖÊÂÎñ»¹²»ÊÇÒ»¸öÐèÇ󣬵«ÊÇΪÁ˰²È«Æð¼û£¬×îºÃ»¹ÊǼǼÿ¸öÇëÇó£¬ÖÁÉÙÊÇΪÁËQA£¨ÖÊÁ¿±£Ö¤£©µÄÄ¿µÄ¡£ÔÚÉú²ú»·¾³£¬¿ÉÄÜ»áÏÞÖÆ»ò¼õÉÙÈÕÖ¾£¬µ«ÊÇÏÖÔÚÎÒÃÇÒª·ÅһЩ¼òµ¥µÄÈÕÖ¾°ïÖú¿ª·¢ÕßÖØÏÖQAÕÒµ½µÄbugs¡£

ÏÖÔÚ£¬µ±ÀÛ»ý»ý·ÖºÍ¶Ò»»»ý·Öʱ£¬Ìí¼ÓÈÕÖ¾£¬ÆäÓà´úÂëºÍ֮ǰµÄÒ»Ñù¡£

/// <summary>
/// ¸Ã·½·¨°üº¬ÁË»ý·ÖϵͳÀÛ»ý¿Í»§»ý·ÖµÄÂß¼­ºÍ¹æÔò
/// </summary>
/// <param name="agreement">×âÁÞЭÒéʵÌå</param>
public void Accrue(RentalAgreement agreement)
{

Console.WriteLine ("Accrue:{0} ", DateTime.Now);
Console.WriteLine ("Customer:{0}", agreement.Customer.Id);
Console.WriteLine ("Vehicle:{0}", agreement.Vehicle.Id);
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = (int)rentalTimeSpan. TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >=Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays *pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id ,points);
Console.WriteLine ("Accrue Complete£º {0}",DateTime.Now);
}

public void Redeem (Invoice invoice, int numberOfDays)
{
Console.WriteLine ("Redeem:{0}", DateTime.Now);
Console.WriteLine ("Invoice:{0}", invoice.Id);
var pointsPerDay = 10;
if (invoice.Vehicle.Size> =Size.Luxury)
{
pointsPerDay = 15;
}
var totalPoints = pointsPerDay* numberOfDays;
invoice.Discount = numberOfDays*i nvoice.CostPerDay;
_loyaltyDataService.SubstractPoints (invoice.Customer.Id, totalPoints);
Console.WriteLine ("Redeem Complete:{0} ", DateTime.Now);
}

ÏÖÔÚ»¹²»ÊǺÜÔã¸â£¬Ö»²»¹ýÔÚÿ¸öʵÏÖÖÐÌí¼ÓÁ˼¸ÐдúÂë¶øÒÑ¡£ÔÛÃǼÌÐøÍùÏÂ×ߣ¡

·ÀÓùÐÔ±à³Ì

ÒòΪÎÒÃǵÄÒµÎñÂß¼­Ã»ÓжԴ«ÈëµÄ²ÎÊý½øÐпØÖÆ£¬Òò´Ë±ØÐëÒª¼ì²éÒ»ÏÂÊÇ·ñÊÇ×µÄÇé¾°¡£±ÈÈ磬Èç¹ûAccrue·½·¨´«ÈëÒ»¸önull»áÔõÑù£¿ÎÒÃǵÄÒµÎñÂß¼­²»ÄÜ´¦ÀíÕâ¸ö£¬ËùÒÔ»áÅ×Òì³££¬µ«ÎÒÃÇÏ£ÍûËüÄܵ÷ÓÃÎÒÃǵÄAPI´¦ÀíÕâ¸öÒì³££¬Èç¹û´¦Àí²»ÁË£¬¾ÍÌáÐÑUI¿ª·¢Õß»òQA·¢ÉúÁËһЩ´íÎóµÄ¶«Î÷¡£ÕâÖÖÕÜѧ¾Í½Ð·ÀÓùÐÔ±à³Ì£¬Ö»ÊÇΪÁ˼õÉÙΣÏÕ³¡¾°µÄ·çÏÕ¡£

ÏÂÃæÎÒÃÇʹÓ÷ÀÓùÐÔ±à³Ì¼ì²é´«Èë²ÎÊýΪnullµÄÎÞЧ³¡¾°£º

public void Accrue (RentalAgreement agreement)
{
//·ÀÓùÐÔ±à³Ì
if (agreement==null)
{
throw new Exceptio n("agreementΪnull£¡");
}
//ÈÕÖ¾
Console.WriteLine ("Accrue:{0}",DateTime.Now);
Console.WriteLine ("Customer:{0}" ,agreement.Customer.Id);
Console.WriteLine ("Vehicle:{0}", agreement.Vehicle.Id);
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = (int)rentalTimeSpan.TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >=Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays *pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id,points);
Console.WriteLine ("Accrue Complete£º {0}", DateTime.Now);
}

ÎÒÃÇÒ²¿ÉÒÔ¼ì²éRentalAgreementµÄÊôÐÔ£¬µ«ÏÖÔÚÉÏÃæµÄ¾Í×ã¹»ÁË¡£RedeemµÄʵÏÖÒ²ÓÐÏàͬµÄÎÊÌ⣬numberOfDays²ÎÊýµÄÖµ²»ÄÜСÓÚ1£¬Invoice²ÎÊýÒ²²»ÄÜΪnull£¬Òò´ËÒ²±ØÐëʹÓ÷ÀÓùÐÔ±à³Ì£º

public void Redeem (Invoice invoice, int numberOfDays)
{
//·ÀÓùÐÔ±à³Ì
if (invoice==null)
{
throw new Exception ("invoiceΪnull£¡");
}
if (numberOfDays<=0)
{
throw new Exception ("numberOfDays ²»ÄÜСÓÚ1£¡");
}
//logging
Console.WriteLine ("Redeem:{0} ",DateTime.Now);
Console.WriteLine ("Invoice:{0} ",invoice.Id);
var pointsPerDay = 10;
if (invoice.Vehicle.Size> =Size.Luxury)
{
pointsPerDay = 15;
}
var totalPoints = pointsPerDay *numberOfDays;
invoice.Discount = numberOfDays *invoice.CostPerDay;
_loyalt yDataService.SubstractPoints (invoice.Customer.Id, totalPoints);
Console.WriteLine ("Redeem Complete: {0}",DateTime.Now);
}

ÏÖÔÚÎÒÃǵĴúÂ뿪ʼ±äµÃ¾ßÓзÀÓùÐÔÁË£¬Èç¹ûÔÚºËÐÄÂß¼­µÄ¿ØÖÆÖ®Íâ·¢ÉúÁË´íÎó£¬Ò²²»»áÓ°Ïìµ½ÎÒÃÇÁË¡£

ÔÚÌí¼ÓÁËÈÕÖ¾ºÍ·ÀÓùÐÔ´úÂëÖ®ºó£¬AccrueºÍRedeem·½·¨¿ªÊ¼±äµÃÓе㳤ÁË£¬Ò²ÓеãÖØ¸´£¬µ«¼ÌÐø¿´Ò»ÏÂÊÂÎñºÍÖØÊÔÂß¼­¡£

ʹÓÃÊÂÎñºÍÖØÊÔ

Èç¹ûÎÒÃÇʹÓÃÁ˲»Ö¹Ò»¸öÊý¾Ý²ã²Ù×÷£¬ÎªÁËʹÕâЩ²Ù×÷¾ßÓÐÔ­×ÓÐÔ£¬ÄÇôÊÂÎñÊDZØÐëµÄ¡£Ò²¾ÍÊÇ˵£¬ÎÒÃÇÏëÒªËùÓеÄÊý¾Ý²ãµ÷Óö¼³É¹¦£¨Ìá½»£©£¬ÒªÃ´¶¼Ê§°Ü£¨»Ø¹ö£©¡£¼ÙÉ裬ÎÒÃÇ¿ÉÒÔ½«ÊÂÎñ·Åµ½ÒµÎñÂß¼­²ã¡£

¼ÙÉèµ×²ãµÄÊý¾Ý²ã»áʹÓúÍ.NETÄÚÖõÄÊÂÎñÀàTransactionScope¼æÈݵļ¼Êõ£¬½áºÏtry/catch¿é£¬ÎÒÃÇ¿ÉÒÔ¸øAccrue·½·¨Ìí¼ÓÊÂÎñ´úÂ룺

public void Accrue(RentalAgreement agreement)
{
//·ÀÓùÐÔ±à³Ì
if (agreement==null)
{
throw new Exception ("agreementΪnull£¡");
}
//ÈÕÖ¾
Console.WriteLine ("Accrue:{0} ",DateTime.Now);
Console.WriteLine ("Customer:{0} ",agreement.Customer.Id);
Console.WriteLine ("Vehicle:{0} ", agreement.Vehicle.Id);
using (var ts= new TransactionScope()) //¿ªÊ¼Ò»¸öÐÂÊÂÎñ
{
try
{
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = ( int)rental TimeSpan.TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >= Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays * pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id, points);
ts.Complete(); //µ÷ÓÃComplete·½·¨±íÃ÷ÊÂÎñ³É¹¦Ìá½»
}
catch (Exception ex)
{
throw;//ûÓе÷ÓÃComplete·½·¨£¬ÊÂÎñ»á»Ø¹ö
}
}
Console.WriteLine ("Accrue Complete£º{0}", DateTime.Now);
}

¼Çס£¬Ö»Óе÷ÓÃÁËÊÂÎñµÄComplete·½·¨£¬ÊÂÎñ²Å»áÌá½»£¬·ñÔò¾Í»á»Ø¹ö¡£Èç¹ûÅ׳öÁËÒì³££¬ÕâÀïÎÒÃÇÖ»ÊÇÖØÐÂÅ׳ö£¬ÏàËÆµØ£¬Ò²¿ÉÒÔÔÚRedeem·½·¨ÖÐʹÓÃTransactionScope,ÕâÀï²»ÔÙÌùÁË£¬Çë×ÔÐп´Ô´Âë¡£

ÉÏÃæµÄ´úÂ뿪ʼ±ä³¤¡¢±ä³óÁË£¬Ô­Ê¼µÄÒµÎñÂß¼­´úÂëÖÜΧ°üÁ˺ܶàºÍºáÇйØ×¢µãÓйصĴúÂë¿é£ºlogging£¬·ÀÓùÐÔ±à³ÌºÍÊÂÎñ´úÂë¡£

µ«ÊÇÎÒÃÇ»¹Ã»×öÍ꣬¼ÙÉèµ×²ãµÄÊý¾Ý³Ö¾Ã²ãż¶û»á³öÏÖ¸ßÁ÷Á¿£¬¿ÉÄܾͻᵼÖÂijЩÇëÇóʧ°Ü£¨±ÈÈ磬Å׳ö³¬Ê±Òì³££©¡£Èç¹ûÊÇÄÇÖÖÇé¿ö£¬Ö´Ðм¸´ÎÖØÊԻᱣ³Ö³ÌÐòƽ»¬ÔËÐУ¨¾¡¹ÜÔÚ¸ßÁ÷Á¿ÆÚ¼äÓеãÂý£©¡£Í¨¹ýÔÚÊÂÎñÖзÅÒ»¸öÑ­»·£¬Ã¿´ÎÊÂÎñ»Ø¹öʱ£¬ÎÒÃǾÍÔö¼ÓÖØÊÔ´ÎÊý£¬Ò»µ©ÖØÊÔ´ÎÊý´ïµ½ÏÞÖÆÖµ£¬ÎÒÃǾͲ»¹ÜÁË£¬ÈçÏ£º

public void Accrue (RentalAgreement agreement)
{
//·ÀÓùÐÔ±à³Ì
if (agreement==null)
{
throw new Exception ("agreementΪnull£¡");
}
//ÈÕÖ¾
Console.WriteLine ("Accrue:{0}", DateTime.Now);
Console.WriteLine ("Customer:{0}", agreement.Customer.Id);
Console.WriteLine("Vehicle:{0}",agreement.Vehicle.Id);
using (var ts= new TransactionScope())//¿ªÊ¼Ò»¸öÐÂÊÂÎñ
{
var retries = 3;//ÖØÊÔÊÂÎñ3´Î
var succeeded = false;
while (!succeeded) //һֱѭ»·£¬Ö±µ½³É¹¦
{
try
{
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = (int)rentalTimeSpan.TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >= Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays * pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id, points);
ts.Complete(); //µ÷ÓÃComplete·½·¨±íÃ÷ÊÂÎñ³É¹¦Ìá½»
succeeded = true; //³É¹¦ºóÉèÖÃΪtrue£¬È·±£×îºóÒ»´ÎÑ­»·µü´ú
Console.WriteLine ("Accrue Complete£º {0}", DateTime.Now);//Õâ¾äÒÆÈëtryÀï
}
catch
{
if (retries>=0)
{
retries--;//Ö±µ½³¢ÊÔÍê´ÎÊýʱ²ÅÖØÅ×Òì³£
}
else
{
throw;//ûÓе÷ÓÃComplete·½·¨£¬ÊÂÎñ»á»Ø¹ö
}

}
}
}

}

ÏàËÆµØ£¬ÎÒÃÇÒ²ÒªÔÚRedeem·½·¨ÖÐÌí¼Ó£¬ÕâÀï²»×öÁË£¬Ê¡ÂÔ¡£ÎÊÌâÔ½À´Ô½Ã÷ÏÔÁË£¬ºáÇйØ×¢µã»ù±¾ÉÏÕ¼¾ÝÁËÕâ¸ö·½·¨µÄÒ»°ë´úÂë¡£µ«ÊÇÎÒÃÇ»¹Ã»ÓÐ×öÍ꣬ÎÒÃÇÐèÒªÌÖÂÛÒ»ÏÂÒì³£´¦Àí¡£

´¦ÀíÒì³£

Ç°Ãæ²»ÊÇÌí¼ÓÁËtry/catchÁËô?ÄѵÀ»¹²»¹»£¿Ò²Ðí£¡±ÈÈ磬·þÎñÆ÷ÀëÏßÁË£¬ÖØÊÔ´ÎÊýµ½´ïÏÞÖÆÁË£¬Òì³£»¹ÊÇ»áÖØÅ׳öÈ¥£¬Èç¹ûÊÇÕâÖÖÇé¿ö£¬ÎÒÃǾÍÐèÒªÔÚ³ÌÐò±ÀÀ£Ç°´¦ÀíÕâ¸öÒì³£¡£

Òò´ËÎÒÃÇÐèÒªÔÚ·ÀÓùÐÔ±à³ÌºóÔÙÌí¼ÓÒ»¸ötry/catch¿é°ü¹üÆäËûËùÓеĴúÂ룬ÈçÏ£º

public void Accrue(RentalAgreement agreement)
{
//·ÀÓùÐÔ±à³Ì
if (agreement==null)
{
throw new Exception ("agreementΪnull£¡");
}
//ÈÕÖ¾
Console.WriteLine ("Accrue:{0}", DateTime.Now);
Console.WriteLine ("Customer:{0}", agreement.Customer.Id);
Console.WriteLin e("Vehicle:{0}", agreement.Vehicle.Id);
try
{
using (var ts = new TransactionScope())//¿ªÊ¼Ò»¸öÐÂÊÂÎñ
{
var retries = 3;//ÖØÊÔÊÂÎñ3´Î
var succeeded = false;
while (!succeeded)//һֱѭ»·£¬Ö±µ½³É¹¦
{
try
{
var rentalTimeSpan = agreement.EndDate.Subtract (agreement.StartDate);
var numberOfDays = (int)rentalTimeSpan.TotalDays;
var pointsPerDay = 1;
if (agreement.Vehicle.Size >= Size.Luxury)
{
pointsPerDay = 2;
}
var points = numberOfDays * pointsPerDay;
//µ÷ÓÃÊý¾Ý·þÎñ´æ´¢¿Í»§»ñµÃµÄ»ý·Ö
_loyaltyDataService.AddPoints (agreement.Customer.Id, points);
ts.Complete(); //µ÷ÓÃComplete·½·¨±íÃ÷ÊÂÎñ³É¹¦Ìá½»
succeeded = true; //³É¹¦ºóÉèÖÃΪtrue£¬È·±£×îºóÒ»´ÎÑ­»·µü´ú
Console.WriteLine ("Accrue Complete£º {0}", DateTime.Now);//Õâ¾äÒÆÈëtryÀï
}
catch
{
if (retries >= 0)
{
retries--;//Ö±µ½³¢ÊÔÍê´ÎÊýʱ²ÅÖØÅ×Òì³£
}
else
{
throw;//ûÓе÷ÓÃComplete·½·¨£¬ÊÂÎñ»á»Ø¹ö
}

}
}
}

}
catch (Exception ex)
{
if (!ExceptionHelper.Handle(ex)) //Èç¹ûûÓд¦ÀíÒì³££¬¼ÌÐøÖØÅ×
{
throw ex;
}
}

}

ExceptionHelperÊÇ×Ô¶¨ÒåµÄÒì³£´¦Àí°ïÖúÀ࣬¸²¸ÇÁ˸ö±ðÒì³£µÄ´¦Àí£¬Èç¹ûÊÇûÓи²¸ÇµÄÒì³££¬ÎÒÃÇ¿ÉÄÜÐèÒª¼Ç¼ÈÕÖ¾£¬²¢¸æË߿ͻ§³öÏÖÁËʲôÒì³£¡£ÏàËÆµØ£¬Redeem·½·¨Ò²Òª×öÏàͬµÄ´¦Àí£¬´Ë´¦Ê¡ÂÔ¡£

´Ëʱ£¬ÎÒÃÇÒѾ­ÊµÏÖÁËËùÓзǹ¦ÄÜÐèÇó£ºlogging£¬·ÀÓùÐÔ±à³Ì£¬ÊÂÎñ£¬ÖØÊÔ£¬ºÍÒì³£´¦Àí¡£½«ÕâЩ´¦ÀíºáÇйØ×¢µãµÄ´úÂëÌí¼Óµ½Ô­Ê¼µÄAccrueºÍRedeem·½·¨ÖÐʹµÃËüÃÇÅòÕͳɾ޴óµÄ·½·¨¡£ÏÖÔÚ´úÂë¿ÉÒÔÈ¥Éú²ú»·¾³£¨»ò¸ü¿ÉÄÜÈ¥QA/Ô¤·¢²¼»·¾³£©£¬µ«ÊÇÕâ´úÂëÌ«Ôã¸âÁË£¡

Äã¿ÉÄÜÔÚÏëÕâ¸öÃèÊöÓеã¹ýÁË£¬²¢²»ÊÇËùÓеĺáÇйØ×¢µã¶¼ÊDZØÐëµÄ£¬Êǵģ¬Äã¿ÉÄÜ´ó¶àÊýÇé¿öÖ»ÐèÒªÒ»Á½¸öºáÇйØ×¢µã£¬Ò»Ð©¹Ø×¢µã¿ÉÒÔÒÆµ½Êý¾Ý²ã»òUI²ã¡£µ«ÕâÀïҪ˵Ã÷µÄµÀÀíÊǺáÇйØ×¢µã¿ÉÒÔʹÄãµÄ´úÂë±äÔÓÂÒ£¬Ê¹µÃ´úÂë¸üÄÑÔĶÁ¡¢Î¬»¤ºÍµ÷ÊÔ¡£

²»Ê¹ÓÃAOPÖØ¹¹

ÊÇʱºòÕûÀíÏ´úÂëÁË£¬ÒòΪAccrueºÍRedeem·½·¨ÖÐÓкܶàÖØ¸´´úÂ룬ÎÒÃÇ¿ÉÒÔ°ÑÕâЩ´úÂë·Åµ½ËüÃÇ×Ô¼ºµÄÀà»ò·½·¨ÖС£Ò»ÖÖÑ¡ÔñÊǽ«ËùÓеķǹ¦ÄܹØ×¢µãÖØ¹¹µ½¾²Ì¬·½·¨ÖУ¬ÕâÊǸöâÈÖ÷Ò⣬ÒòΪÕâ»á½«ÒµÎñÂß¼­½ôñîºÏµ½·Ç¹¦ÄܹØ×¢µã´úÂëÖУ¬ËäȻʹ·½·¨¿´ÉÏÈ¥¸ü¶Ì¸ü¿É¶ÁÁË£¬µ«ÈÔÈ»ÁôÏÂÁË·½·¨×öµÄÊÂÇéÌ«¶àµÄÎÊÌâ¡£ÄãÒ²¿ÉÒÔʹÓÃDI²ßÂÔ£¬½«ËùÓеÄlogging£¬·ÀÓùÐÔ±à³ÌºÍÆäËû·þÎñ´«¸øLoyaltyAccrualServiceºÍLoyaltyRedemptionServiceµÄ¹¹Ô캯Êý£º

public class LoyalRedemptionServiceRefactored :ILoyaltyRedemptionService
{
private readonly ILoyaltyDataService _loyaltyDataService;
private readonly IExceptionHandler _exceptionHandler;//Òì³£´¦Àí½Ó¿Ú
private readonly ITransactionManager _transactionManager;//ÊÂÎñ¹ÜÀíÕß

public LoyalRedemptionServiceRefactored (ILoyaltyDataService loyaltyDataService, IExceptionHandler exceptionHandler,
ITransactionManager transactionManager)
{
_loyaltyDataService = loyaltyDataService;
_exceptionHandler = exceptionHandler;//ͨ¹ýÒÀÀµ×¢Èë´«Èë
_transactionManager = transactionManager;
}

public void Redeem (Invoice invoice, int numberOfDays)
{
//·ÀÓùÐÔ±à³Ì
if (invoice==null)
{
throw new Exception ("InvoiceΪnullÁË£¡ ");
}
if (numberOfDays<=0)
{
throw new Exception (" numberOfDays²»ÄÜСÓÚ1£¡");
}
//logging
Console.WriteLine ("Redeem: {0}", DateTime.Now);
Console.WriteLine ("Invoice: {0}", invoice.Id);

_exceptionHandler.Wrapper(() =>
{
_transactionManager.Wrapper(() =>
{
var pointsPerDay = 10;
if (invoice.Vehicle.Size> =Size.Luxury)
{
pointsPerDay = 15;
}
var totalPoints = numberOfDays *pointsPerDay;
_loyaltyDataService.SubstractPoints ( invoice.Customer.Id, totalPoints);
invoice.Discount = numberOfDays* invoice.CostPerDay;
// logging
Console.WriteLine ("Redeem complete: {0}", DateTime.Now);
});
});
}
}


ÉÏÃæÊÇÖØ¹¹¹ýµÄ°æ±¾£¬IExceptionHandlerµÈµÄ´úÂëûÓÐÌù³öÀ´£¬Çë²é¿´Ô´Â룬Õâ¸ö°æ±¾±È֮ǰµÄºÃ¶àÁË¡£ÎÒ½«Òì³£´¦Àí´úÂëºÍÊÂÎñ/ÖØÊÔ´úÂë·Ö±ð·Åµ½ÁËIExceptionHandlerºÍITransactionManagerÖУ¬ÕâÖÖÉè¼ÆÓÐËüµÄÓÅÊÆ£¬Ò»ÊÇËü°ÑÄÇЩ´úÂë¶Î·Åµ½ÁËËûÃÇ×Ô¼ºµÄÀàÖУ¬ÒÔºó¿ÉÒÔÖØÓã»¶þÊÇͨ¹ý¼õÉÙÁ˺áÇйØ×¢µãµÄÔëÒôʹµÃ´úÂëÔĶÁ¸üÈÝÒס£

µ±È»£¬Accrue·½·¨Ò²¿ÉÒÔÖØ¹¹³ÉÕâÑù£¬´Ë´¦ÂÔ¹ý¡£Öع¹Ö®ºó£¬´úÂëºÍ×îԭʼµÄ״̬²î²»¶àÁË¡£µ«Êǹ¹Ô캯ÊýºÃÏñÌ«ÅÓ´óÁË,Ò²¾ÍÊÇÒÀÀµÌ«¶àÁË£¬Êµ¼ÊÉÏ£¬ÕâÀï¿ÉÒÔÓÅ»¯Ò»Ï£¬ÍùÏ¿´¡£

Code Smells¡¾´úÂëÒìζ¡¿

´úÂëÒìζÊÇÒ»¸öÙµÓ±¾ÖÊÉÏËü²»ÊÇbug£¬µ«Ëü°µÊ¾ÁË¿ÉÄÜ»á´æÔÚÒ»¸öÎÊÌâ¡£¾ÍÏñ±ùÏäÀïµÄÄÑÎÅÆøÎ¶±íÃ÷±³ºóÓи¯ÀõÄÈâÒ»Ñù£¬´úÂëÒìζ¿ÉÄÜָʾÁ˵±Ç°µÄÉè¼Æ²»Ì«ºÃ£¬Ó¦¸Ã±»Öع¹¡£ÏêϸÁ˽â´úÂëÒâ棬¿ÉÒÔµã»÷ÔĶÁ¡£

ÎÒÃÇ¿ÉÒÔ½«Òì³£´¦ÀíºÍÊÂÎñ¹ÜÀíºÏ²¢³ÉÒ»¸ö·þÎñ£¬ÈçÏ£º

public interface ITransactionManager2
{
void Wrapper (Action method);
}

public class TransactionManager2 : ITransactionManager2
{
public void Wrapper (Action method)
{
using (var ts= new TransactionScope())
{
var retires = 3;
var succeeded = false;
while (!succeeded)
{
try
{
method();
ts.Complete();
succeeded = true;
}
catch (Exception ex)
{
if (retires >= 0)
retires--;
else
{
if (!ExceptionHelper.Handle(ex))
throw;
}
}
}
}
}
}


´¦Àí×¢ÈëÒÀÀµ¹ý¶àµÄÁíÒ»ÖÖ·½·¨Êǽ«ËùÓеķþÎñÒÆµ½Ò»¸ö¾ÛºÏ·þÎñ»òÕßÃÅÃæ·þÎñ£¨¼´£¬Ê¹ÓÃÃÅÃæÄ£Ê½½«ËùÓеÄС·þÎñ×éºÏ³ÉÒ»¸ö·þÎñÀ´×éÖ¯ÕâЩС·þÎñ£©£¬ÎÒÃÇÕâ¸öÀý×ÓÖУ¬TransactionManagerºÍExceptionHandler·þÎñÊǶÀÁ¢µÄ£¬µ«ÊÇ¿ÉÒÔʹÓõÚÈý¸öÃÅÃæÀàÀ´×éÖ¯ËüÃǵÄʹÓá£

ÃÅÃæÄ£Ê½ The Facade Pattern

ÃÅÃæÄ£Ê½Îª¸ü´óµÄ»òÕ߸ü¸´ÔӵĴúÂë¶ÎÌṩÁËÒ»¸ö¼ò»¯½Ó¿Ú£¬±ÈÈ磬һ¸öÌṩÁËÐí¶à·½·¨ºÍÑ¡ÏîµÄ·þÎñÀà¿ÉÒԷŵ½Ò»¸öÃÅÃæ½Ó¿ÚÖУ¬ÕâÑù¾Í¿ÉÒÔͨ¹ýÏÞÖÆÑ¡Ïî»òÕßÌṩ¼ò»¯·½·¨µÄ×Ó¼¯À´½µµÍ¸´ÔÓ¶È¡£

public interface ITransactionFacade
{
void Wrapper(Action method);
}

public class TransactionFacade : ITransactionFacade
{
private readonly ITransactionManager _transactionManager;
private readonly IExceptionHandler _exceptionHandler;

public TransactionFacade(ITransactionManager transactionManager, IExceptionHandler exceptionHandler)
{
_transactionManager = transactionManager;
_exceptionHandler = exceptionHandler;
}

public void Wrapper(Action method)
{
_exceptionHandler.Wrapper(()=>
_transactionManager.Wrapper(method)
);
}
}

ÕâÑùÐ޸ĺó£¬AccrualºÍRedemption·þÎñ·½·¨ÖеÄWrapperÑù°å´úÂë¾Í¼õÉÙÁ˺ܶ࣬¸ü¸É¾»ÁË¡£µ«ÊÇ»¹´æÔÚ·ÀÓù±à³ÌºÍloggingµÄÎÊÌâ¡£

ʹÓÃ×°ÊÎÆ÷Ä£Ê½ÖØ¹¹

²»Ê¹ÓÃAOPÖØ¹¹´úÂëµÄÁíÒ»ÖÖ·½Ê½ÊÇʹÓÃ×°ÊÎÆ÷ģʽ»ò´úÀíÆ÷ģʽ¡£¾ç͸һÏ£º×°ÊÎÆ÷/´úÀíÆ÷ģʽֻÊÇAOPµÄÒ»ÖÖ¼òµ¥ÐÎʽ¡£

ÊÔÏ룬Èç¹ûÓÐÒ»ÖÖ·½·¨¿ÉÒÔ½«ÉÏÃæËùÓеķ½·¨ºÏÆðÀ´³ÉΪһÖÖ·½·¨£¬Ê¹µÃ´úÂë»Øµ½×î³õʼ״̬£¨Ö»ÓÐÒµÎñÂß¼­£©£¬Äǽ«ÊÇ×îºÃµÄÁË¡£ÄǾͶÁÆðÀ´×î¼òµ¥£¬ÓÐ×îÉٵĹ¹Ô캯Êý×¢ÈëµÄ·þÎñ¡£µ±ÒµÎñÂß¼­±ä»¯Ê±£¬ÎÒÃÇÒ²²»±Øµ£ÐÄÍü¼Ç»òºöÂÔÁËÕâЩºáÇйØ×¢µã£¬´Ó¶ø¼õÉÙÁ˱ä¸üµÄ´ú¼Û¡£

±ä¸üµÄ´ú¼Û

Èí¼þ¹¤³ÌÖв»±äµÄ¶«Î÷¾ÍÊDZ仯£¬ÐèÇó±äÁË£¬ÒµÎñ¹æÔò±äÁË£¬¼¼Êõ±äÁË¡£ÒµÎñÂß¼­»òÐèÇóµÄÈκαä¸ü¶Ô´¦Àíԭʼ°æ±¾µÄÒµÎñÂß¼­¶¼ÊÇÌôÕ½ÐԵģ¨ÔÚ´úÂëÖØ¹¹Ö®Ç°£©¡£

ÐèÇó±ä¸ü

ÒòΪÐí¶àÔ­Òò£¬ÐèÇó»á±ä¸ü¡£ÐèÇóÒ»¿ªÊ¼¿ÉÄÜÊǺÜÄ£ºýµÄ£¬µ«ÊÇËæ×ÅÈí¼þ¿ªÊ¼³ÉÐÍ£¬¾Í»á±äµÃ¸ü¼Ó¾ßÌå¡£ÏîÄ¿¾­ÀíµÈÈ˾ͻá¸Ä±äÏë·¨£¬¶ÔËûÃÇÀ´Ëµ¿´ËƺÜСµÄ±ä»¯£¬¿ÉÄÜÔÚ´úÂëÖÐÒâζןܴóµÄ²»Í¬¡£

ËäÈ»ÎÒÃǶ¼ÖªµÀÐèÇó»á±äÊǸöÕæÀí£¬²¢ÇÒÒ²ÒѾ­·´¸´¼ûÖ¤ÁË£¬µ«ÈÔÈ»ÔÚ·¸Ò»¸ö´í£¬ÄǾÍÊDZàÂëʱºÃÏñʲô¶¼²»»á¸Ä±ä¡£×÷Ϊһ¸öºÃµÄ¿ª·¢Õߣ¬²»½öÒª½ÓÊÜÐèÇóµÄ±ä»¯£¬»¹ÒªÆÚ´ýÐèÇó±ä»¯¡£

ÏîÄ¿µÄ´óСȷʵºÜÖØÒª£¬Èç¹ûÄãÊÇÒ»¸öÈ˱àдһ¸ö¼òµ¥µÄÈí¼þ£¨±ÈÈçÒ»¸ö¾ßÓÐÁ½Èý¸ö±íµ¥ºÍÐí¶à¾²Ì¬ÄÚÈݵÄÍøÕ¾£©£¬ÄÇô±ä¸üµÄ´ú¼Û¿ÉÄܺܵͣ¬ÒòΪ¸Ä¶¯µÄµØ·½ºÜÉÙ¡£

·½·¨Ç©Ãû±ä¸ü

¸ø·½·¨Ìí¼Ó»òÒÆ³ý²ÎÊý¾Í»áµ¼Ö·½·¨Ç©Ãû±ä¸ü¡£Èç¹ûÒÆ³ýÁËÒ»¸ö²ÎÊý£¬¾Í±ØÐëÒÆ³ý¸Ã²ÎÊýµÄ·ÀÓùÐÔ±à³Ì£¬·ñÔò£¬ÏîÄ¿±àÒ벻ͨ¹ý¡£Èç¹ûÐÞ¸ÄÁËÒ»¸ö²ÎÊýµÄÀàÐÍ£¬ÄÇô·ÀÓùÐÔ±à³Ì±ß½çÇé¿öÒ²»á¸Ä±ä¡£¸üΣÏÕµÄÊÇ£¬Èç¹ûÌí¼ÓÁËÒ»¸ö²ÎÊý£¬¾Í±ØÐëÌí¼Ó¸Ã²ÎÊýµÄ·ÀÓùÐÔ±à³Ì£¬²»ÐÒµÄËÆºõ£¬±àÒëÆ÷²»»á°ïÄã×öÕâ¸ö£¬×Ô¼º±ØÐëÒª¼ÇµÃ×öÕâ¼þÊ¡£

¿´Ò»ÏÂ֮ǰµÄAccrue·½·¨£¬Ç©Ãû¸Ä±äµÄµØ·½»áÁ¢¼´Ó°Ïì·ÀÓù±à³ÌºÍÈÕÖ¾¼Ç¼£¬ÈçÏ£º

public void Accrue(RentalAgreement agreement) {
// defensive programming
if(agreement == null) throw new ArgumentNullException("agreement");
// logging
Console.WriteLine("Accrue: {0}", DateTime.Now);
Console.WriteLine("Customer: {0}", agreement.Customer.Id);
Console.WriteLine("Vehicle: {0}", agreement.Vehicle.Id);
// ... snip ...
// logging
Console.WriteLine("Accrue complete: {0}", DateTime.Now);
}

Èç¹û²ÎÊýÃû´Óagreement±ä³ÉrentalAgreement,ÄÇô±ØÐë¼ÇµÃ¸ü¸ÄArgumentNullExceptionµÄ¹¹Ô캯ÊýµÄ×Ö·û´®²ÎÊý¡£Èç¹û·½·¨Ãû±¾Éí±äÁË£¬Ò²±ØÐë¸ü¸ÄloggingÖмǼµÄ×Ö·û´®·½·¨Ãû¡£ËäÈ»ÓкܶàÖØ¹¹¹¤¾ß¿ÉÒÔ¸¨Öú£¬ÈçResharp,µ«ÊÇÆäËûµÄ»¹ÒªÒÀÀµÄã×Ô¼ººÍÍŶӵľ¯Ìè¡£

ÍŶӿª·¢

Ò»¸öÈË¿ª·¢¾ÍËãÁË¡£¼ÙÉèÓиöеÄÐèÇó£¬ILoyaltyAccureService½Ó¿ÚÐèÒªÌí¼ÓÒ»¸öÐµķ½·¨£¬Ò²ÐíÕâ¸öÈÎÎñ»áÅɸøÆäËû¶ÓÓÑ£¬²¢ÇÒÕâ¸ö¶ÓÓÑʵÏÖÁËÒµÎñÂß¼­²¢Íê³ÉÁËÈÎÎñ¡£²»ÐÒµØÊÇ£¬Õâ¸ö¶ÓÓÑÍü¼ÇÁËʹÓÃTransactionFacadeµÄWrapper·½·¨£¬ËûµÄ´úÂëͨ¹ýÁËUT£¬È»ºó½»¸øÁËQA¡£Èç¹ûÕâÊÇÒ»¸öÃô½ÝÏîÄ¿£¬ÕâÒ²Ðí²»ÊÇ´óÎÊÌ⣺QA»á²¶×½µ½Õâ¸öÎÊÌ⣬²¢Á¢¼´°ÑÕâ¸öÎÊÌⱨ¸æ¸øÄã¡£ÔÚÒ»¸öÆÙ²¼ÏîÄ¿ÖУ¬QA¿ÉÄÜÔÚ¼¸¸öÔÂÖ®ºó²Å»á·¢ÏÖÕâ¸öbug¡£¼¸¸öÔºó£¬Äã¿ÉÄÜÒ²²»¼ÇµÃÔì³ÉÕâ¸öbugµÄÔ­ÒòÁË¡£¾ÍºÃÏñÄãÊÇÍŶÓÖеÄÐÂÔ±¹¤Ò»Ñù¡£

×îÔã¸âµÄÇé¿ö£ºËü¿ÉÄÜͨ¹ýÁËQA£¬¼ÙÉèµÄÒì³£»òÖØÊÔÌõ¼þ²»ÊDZØÒªµÄ»òÕßûÓб»×¢Òâµ½£¬ÕâÑù£¬´úÂë¾ÍûÓо­¹ý·ÀÓùÐÔ±à³Ì¡¢logging¡¢ÊÂÎñµÈµÈ½øÈëÁËÉú²ú»·¾³£¬ÕâÑù³ÙÔç³öÎÊÌ⣡

ʹÓÃAOPÖØ¹¹

ÔÙ´ÎÖØ¹¹´úÂ룬Õâ´ÎʹÓÃAOP£¬Ê¹ÓÃNuGetÌí¼ÓPostsharpµ½ÏîÄ¿CarRental.CoreÖУ¬¹ØÓÚÈçºÎÌí¼Ó£¬Çë²é¿´ÉÏһƪÎÄÕ¡£

¿ª·¢¼òµ¥¡¢¶ÀÁ¢µÄlogging

ÏÈÀ´Öع¹Ò»¸ö¼òµ¥µÄºáÇйØ×¢µã£ºlogging¡£µ±·½·¨µ÷ÓÃʱ£¬»á¼Ç¼·½·¨ÃûºÍʱ¼ä´Á¡£´´½¨Ò»¸öÈÕÖ¾ÇÐÃæÀ࣬¼Ì³Ð×ÔOnMethodBoundaryAspect£¬ËüÔÊÐíÎÒÃÇÔÚ·½·¨µÄ±ß½ç²åÈë´úÂ룺

[Serializable]
public class LoggingAspect:OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("{0}:{1}",args.Method.Name,DateTime.Now);
}

public override void OnSuccess(MethodExecutionArgs args)
{
Console.WriteLine("{0} complete:{1}",args.Method.Name,DateTime.Now);
}
}

×¢Ò⣬ÎÒÃÇ¿ÉÒÔͨ¹ýMethodExecutionArgs²ÎÊý»ñµÃ·½·¨Ãû£¬Òò´Ë£¬Õâ¸öÇÐÃæ¿ÉÒÔcÖØ¸´Ê¹Ó㬿ɸøAccureºÍRedeem·½·¨Ê¹Óãº

public class LoyaltyAccrualService:ILoyaltyAccrualService
{
[LoggingAspect]
public void Accrue(RentalAgreement agreement)
{
//...
}
}

public class LoyalRedemptionService:ILoyaltyRedemptionService
{
[LoggingAspect]
public void Redeem(Invoice invoice, int numberOfDays)
{
//...
}
}

ÏÖÔھͿÉÒÔ´ÓÕâЩ·½·¨ÖÐÒÆ³ýlogging´úÂëÁË¡£³ý´ËÖ®Í⣬ÎÒÃÇ»¹Ã»ÓдòÓ¡´«Èë²ÎÊýµÄId£¬±ÈÈçCustomer.Id¡£ÓÐÁËPostsharp,ÎÒÃÇ¿ÉÒÔÈ¡µ½ËùÓеĴ«Èë²ÎÊý£¬µ«ÎªÁËÈ¡µ½Id,±ØÐ뻹µÃ×öµãÊÂÇé¡£

public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("{0}:{1}",args.Method.Name,DateTime.Now);
foreach (var argument in args.Arguments)//±éÀú·½·¨µÄ²ÎÊý
{
if (argument.GetType()==typeof(RentalAgreement))
{
Console.WriteLine("Customer:{0}", ((RentalAgreement)argument).Customer.Id);
Console.WriteLine("Vehicle:{0}", ((RentalAgreement)argument).Vehicle.Id);
}
if (argument.GetType()==typeof(Invoice))
{
Console.WriteLine("Invoice:{0}",((Invoice)argument).Id);
}
}
}

¾ÍÕâ¸öÀý×ÓÀ´Ëµ£¬ÕâÑùûÎÊÌâÁË£¬µ«ÊǶÔÓÚÒ»¸ö´óÒ»µãµÄÓ¦Ó㬿ÉÄÜ»áÓм¸Ê®¸öÉõÖÁ¼¸°Ù¸ö²»Í¬µÄÀàÐÍ£¬Èç¹ûÐèÇóÊǼǼʵÌåIdºÍÐÅÏ¢£¬ÄÇô¿ÉÒÔÔÚʵÌåÉÏʹÓÃÒ»¸ö¹«¹²½Ó¿Ú£¨»ò»ùÀࣩ¡£±ÈÈ磬Èç¹ûInvoiceºÍRentalAgreement¶¼ÊµÏÖÁËILoggable½Ó¿Ú£¬¸Ã½Ó¿Ú¾ßÓÐÒ»¸ö·½·¨string LogInfo(),´úÂë¿ÉÒÔÕâÑùд:

public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("{0}:{1}",args.Method.Name,DateTime.Now);
foreach (var argument in args.Arguments)//±éÀú·½·¨µÄ²ÎÊý
{
if (argument!=null)
{
if (typeof(ILoggable).IsAssignableFrom(argument.GetType()))
{
Console.WriteLine((ILoggable)argument.LogInfo());
}
}

}
}

ÏÖÔÚAccureºÍRedeem·½·¨¿ªÊ¼ÊÕËõÁË£¬ÒòΪÎÒÃǽ«logging¹¦ÄÜÒÆµ½ÁËËü×Ô¼ºµÄÀàÈÕÖ¾ÇÐÃæÖÐÈ¥ÁË¡£

ÖØ¹¹·ÀÓùÐÔ±à³Ì

ÏÂÃæ»¹ÊÇʹÓÃOnMethodBoundaryAspect»ùÀàÖØ¹¹·ÀÓùÐÔ±à³Ì£¬È·±£Ã»ÓвÎÊýΪnull£¬ÒÔ¼°ËùÓеÄint²ÎÊý²»Îª0»ò¸ºÊý£º

[Serializable]
public class DefensiveProgramming:OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
var parameters = args.Method.GetParameters();//»ñÈ¡ÐβÎ
var arguments = args.Arguments;//»ñȡʵ²Î
for (int i = 0; i < arguments.Count; i++)
{
if (arguments[i]==null)
{
throw new ArgumentNullException(parameters[i].Name);
}
if (arguments[i] is int&&(int)arguments[i]<=0)
{
throw new ArgumentException("²ÎÊý·Ç·¨",parameters[i].Name);
}
}
}
}

Ê×Ïȼì²éʵ²ÎÊÇ·ñΪnull£¬Ö®ºóÔÙÅжϲÎÊýÊÇ·ñÊÇÕûÐÍ£¬²¢ÇÒÊÇ·ñºÏ·¨¡£Èç¹û²»´¦ÀíÕâЩÊÂÇ飬·Ç·¨Öµ»áʹµÃ³ÌÐò±ÀÀ££¬µ«ÕâÀï´¦ÀíÖ®ºóÎÒÃÇ¿ÉÒÔ¿´µ½±ÀÀ£µÄÈ·¶¨Ô­Òò£¨ArgumentNullException»òArgumentException µÄÒì³£ÐÅÏ¢£©¡£

ͬʱ£¬Õâ¸öÀàûÓÐÖ±½ÓñîºÏÈκβÎÊýÀàÐÍ»ò·þÎñÀ࣬ÕâÒâζ×Å¿ÉÒÔÖØ¸´Ê¹ÓÃÔÚ¶à¸ö·þÎñÖС£

[LoggingAspect]
[DefensiveProgramming]
public void Accrue(RentalAgreement agreement)
{
//...ÂÔ
}

[LoggingAspect]
[DefensiveProgramming]
public void Redeem(Invoice invoice, int numberOfDays)
{
//...
}


·ÀÓùÐÔ±à³ÌÇÐÃæ

ÕâÀïдµÄ·ÀÓùÐÔ±à³ÌÇÐÃæ¿ÉÄܲ»ÊDZàдͨÓÃÇÐÃæµÄ×î¼Ñʵ¼ù£¬ÔÚC#ÖУ¬ÎÒÃÇ¿ÉÒÔÖ±½ÓÔÚÿ¸ö²ÎÊýÉÏ·ÅÖÃÌØÐÔ£¬Òò´Ë¿ÉÒÔÕâÑùÌæ´úÇ°ÃæÄÇÖÖ·½·¨¡£Êµ¼ÊÉÏ£¬NugetºÍgithubÉÏÓÐרÃŵÄÀà¿âNullGuard£¬Ò»¸öFody°æ±¾µÄ£¬Ò»¸öPostSharp°æ±¾µÄ£¬´ó¼Ò¿ÉÒÔȥѧϰһÏ¡£

µ½ÕâÀÐèҪ˵Ã÷Ò»ÏÂÁË£¬.NetÖеÄÌØÐÔûÓÐÒ»¶¨µÄ˳Ðò£¬Ò²¾ÍÊÇ˵£¬ÉÏÃæµÄ´úÂëÀ[LoggingAspect]ÌØÐÔÔÚ[DefensiveProgramming]µÄÉÏÃæ£¬²»ÊÇÒâζ×Å[LoggingAspect]ÓÅÏÈÓ¦Óã¬Á½ÕßµÄÓ°ÏìºÍ˳ÐòÎ޹أ¬Ôõô·Å¶¼¿ÉÒÔ¡£

ÓÐÁË·ÀÓùÐÔ±à³ÌÇÐÃæÖ®ºó£¬·þÎñ´úÂëÓÖ¼ò»¯ÁË£¬´úÂë¿É¶ÁÐÔÓÖÌá¸ßÁË£¬ÏÂÒ»²½À´Öع¹ÊÂÎñ¹ÜÀí´úÂë¡£

ΪÊÂÎñºÍÖØÊÔ´´½¨ÇÐÃæ

ÒªÖØ¹¹ÊÂÎñ¹ÜÀí´úÂ룬Õâ´Î²»Ê¹ÓÃOnMethodBoundaryAspect,¶øÊÇʹÓÃMethodInterceptionAspect£¬Ëü²»ÊÇÔÚ·½·¨µÄ±ß½ç²åÈë´úÂ룬¶øÊÇ»áÀ¹½ØÈκθ÷½·¨µÄµ÷Óá£À¹½ØÇÐÃæ»áÔÚÀ¹½Øµ½·½·¨µ÷ÓÃʱִÐÐÇÐÃæ´úÂ룬֮ºóÔÙÖ´ÐÐÀ¹½Øµ½µÄ·½·¨£»¶ø±ß½çÇÐÃæ»áÔÚ·½·¨Ö´ÐÐǰºóÔËÐÐÇÐÃæ´úÂë¡£

[Serializable]
public class TransactionManagement : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
using (var ts = new TransactionScope())
{
var retries = 3;//ÖØÊÔ3´Î
var succeeded = false;
while (!succeeded)
{
try
{
args.Proceed();//¼ÌÐøÖ´ÐÐÀ¹½ØµÄ·½·¨
ts.Complete();//ÊÂÎñÍê³É
succeeded = true;
}

catch (Exception ex)
{
if (retries >= 0)
retries--;
else
throw ex;
}
}
}
}
}

Õâ¸öÇÐÃæÀý×ӵĴúÂëºÍÒµÎñÂß¼­ÖеĴúÂë»ù±¾Ò»Ñù£¬³ýÁËʹÓÃargs.Proceed()·½·¨Ìæ»»ÁËÒµÎñÂß¼­´úÂë¡£Proceed()·½·¨Òâ˼¾ÍÊǼÌÐøÖ´ÐÐÀ¹½Øµ½µÄ·½·¨¡£Í¨¹ýÉÏÃæµÄ´úÂ룬ÎÒÃǵĴúÂëÓÖ¼ò»¯ÁË£¬ÏÂÃæ¼ÇµÃ¸ø·þÎñ·½·¨Ìí¼ÓÌØÐÔ,²¢½«ÒµÎñ´úÂë´ÓÊÂÎñÖÐÒÆ³ý£º

[LoggingAspect]
[DefensiveProgramming]
[TransactionManagement]
public void Accrue(RentalAgreement agreement)
{
//...ÂÔ
}

[LoggingAspect]
[DefensiveProgramming]
[TransactionManagement]
public void Redeem(Invoice invoice, int numberOfDays)
{
//...
}

ΪÁË˵Ã÷ÊÂÎñÇÐÃæÄÜÕý³£¹¤×÷£¬¿ÉÒÔÔÚOnInvokeÄÚ²¿Ç°ºóÌí¼ÓConsole.WriteLine("{0}·½·¨¿ªÊ¼/½áÊø£º{1}", args.Method.Name,DateTime.Now);£¬´òÓ¡³öÀ´¿´Ò»Ï¡£

ÖØ¹¹Òì³£´¦ÀíÇÐÃæ

Òì³£´¦ÀíÇÐÃæÐèҪʹÓÃOnMethodBoundaryAspect£¬»òÕß¿ÉÒÔʹÓÃOnExceptionAspect£¬ÎÞÂÛʹÓÃÄÄÒ»ÖÖ£¬Ñù×Ó¶¼ÊDz¶àµÄ¡£

[Serializable]
public class MyExceptionAspect:OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
if (ExceptionHelper.Handle(args.Exception))
{
args.FlowBehavior=FlowBehavior.Continue;
}
}
}

ExceptionHelperÊÇÎÒ×Ô¼º¶¨ÒåµÄÒì³£´¦Àí¾²Ì¬À࣬ÕâÀï³öÏÖÁËÒ»¸öÐÂÍæÒâFlowBehavior,ËüÖ¸¶¨Á˵±ÇÐÃæÖ´ÐÐÍêÖ®ºó£¬½ÓÏÂÀ´Ôõô°ì£¡ÕâÀïÉèÖÃÁËContinue,Ò²¾ÍÊÇ˵£¬Èç¹ûÒì³£´¦ÀíÍêÁË£¬³ÌÐò¼ÌÐøÖ´ÐУ¬·ñÔò£¬Ä¬ÈϵÄFlowBehaviorÊÇ RethrowException,ÕâÑùµÄ»°£¬ÇÐÃæ¾ÍûЧ¹ûÁË£¬Òì³£ÓÖÔÙ´ÎÅ׳öÀ´ÁË¡£

ÒÆ³ýÒì³£´¦ÀíµÄ´úÂ룬¼ÓÉÏÒì³£´¦ÀíÇÐÃæÌØÐÔ£¬ÖÁ´Ë£¬ËùÓеĺáÇйØ×¢µã¾ÍÖØ¹¹ÍêÁË¡£ÏÂÃæÍêÕûµØ¿´Ò»ÏÂ³ÉÆ·£º

[LoggingAspect]
[DefensiveProgramming]
[TransactionManagement]
[MyExceptionAspect]
public void Accrue (RentalAgreement agreement)
{
var rentalTime = agreement.EndDate.Subtract (agreement.StartDate);
var days = (int) Math.Floor (rentalTime.TotalDays);
var pointsPerDay = 1;
if (agreement.Vehicle.Size> =Size.Luxury)
{
pointsPerDay = 2;
}
var totalPoints = days*pointsPerDay;
_loyaltyDataService.AddPoints (agreement.Customer.Id, totalPoints);
}


[LoggingAspect]
[DefensiveProgramming]
[TransactionManagement]
[MyExceptionAspect]
public void Redeem (Invoice invoice, int numberOfDays)
{
var pointsPerday = 10;
if (invoice.Vehicle.Size> =Size.Luxury)
{
pointsPerday = 15;
}
var totalPoints = numberOfDays *pointsPerday;
_loyaltyDataService.SubstractPoint s(invoice.Customer.Id, totalPoints);
invoice.Discount = numberOfDays* invoice.CostPerDay;
}

¿ÉÒÔ¿´µ½£¬ÕâÑùµÄ´úÂë¿´×źܲ»´í°É£¿Óֻص½ÁË֮ǰ×ʼµÄ´úÂ룬ֻÓÐÒµÎñÂß¼­µÄµ¥Ò»Ö°Ôð״̬£¬ËùÓеĺáÇйØ×¢µã¶¼·Åµ½ÁËËüÃǸ÷×ÔµÄÀàÖÐÈ¥ÁË¡£´úÂë·Ç³£ÈÝÒ×ÔĶÁ¡£

ÔÙÀ´¿´¿´Ê¹ÓÃAOPµÄÓŵ㣺

¸ü¸Ä·½±ã¡£Èç¹û¸ü¸ÄÁË·½·¨µÄ·½·¨Ãû»ò²ÎÊýÃû£¬ÇÐÃæ»á×Ô¶¯´¦Àí¡£ÇÐÃæ²»»á¹ØÐÄÒµÎñÂß¼­ÊÇ·ñ·¢Éú±ä»¯£¨±ÈÈçÿÌì»ý·ÖµÄ±ä»¯£©£¬ÒµÎñÂß¼­Ò²²»»á¹ØÐÄÄãÊÇ·ñ´ÓConsoleÇл»µ½ÁËlog4Net»òNLog£¬³ý·ÇÄãÏëʹÓÃTransactionScopeÖ®ÍâµÄ¶«Î÷´¦ÀíÊÂÎñ»òÕßÐèÒª¸Ä±äÖØÊÔ´ÎÊýµÄ×î´óÖµ¡£

¿ÉÒÔ½«ÕâЩÇÐÃæÖØ¸´¸øÃ¿¸ö·þÎñµÄ¸÷¸ö·½·¨Ê¹Ó㬶ø²»ÊDz»Ê¹ÓÃAOPʱ£¬Ã¿´Î¶¼Òª¸´ÖÆÕ³ÌùÏàËÆµÄ´úÂë¡£

¿ÉÒÔÔÚÕû¸öÀà¡¢ÃüÃû¿Õ¼ä»ò³ÌÐò¼¯Ê¹Óöà¹ã²¥ÇÐÃæ£¬¶ø²»ÓÃÔÚÿ¸ö·½·¨ÉÏÕâÑùд¡£

С½á

ÕâÆªµÄÄ¿µÄÒ»ÊÇÑÝʾһϺáÇйØ×¢µã¿ÉÒÔʹÄãµÃ´úÂëÔàÂҲ³£¹æµÄOOPºÍʹÓúÃÉè¼ÆÄ£Ê½ÔÚÐí¶àÇé¿öÏ¿ÉÒÔ°ïÖúÖØ¹¹´úÂ룬µ«ÊǺܶàÇé¿ö»¹ÊÇ»áÈÃÄãµÄ´úÂëºÍºáÇйØ×¢µã½ôñîºÏ¡£¼´Ê¹ÄãµÄ´úÂë×ñÊØÁËSPRºÍDI£¬´úÂëÒ²»áÏ໥¾À²ø£¬´íÂÒ»òÖØ¸´¡£

¶þÀ´ÊÇ˵Ã÷һϱä¸üµÄ´ú¼ÛÊǺÍÄãµÄ´úÂë¶àôÁé»î¡¢¿É¶ÁºÍÄ£¿é»¯ÊÇÏà¹ØµÄ¡£¼´Ê¹ÒѾ­Öع¹µÄºÜºÃÁË£¬ÈÔÄÜÔÚ´«Í³µÄOOPÖÐÖз¢ÏÖһЩ²»ÈÝÒ×½âñîµÄºáÇйØ×¢µã¡£

ÈýÊÇÑÝʾһÏÂAOP¹¤¾ß£¨ÈçPostSharp£©ÈçºÎÈÃÄã¶ÔºáÇйØ×¢µã½øÐнâñʹÓÃAOPÖØ¹¹µÄ°æ±¾£¬ËùÓеĺáÇйØ×¢µã¶¼ÓÐËü×Ô¼ºµÄÀ࣬·þÎñÀà¼õÉÙµ½Ö»ÓÐÒµÎñÂß¼­ºÍÖ´ÐÐÒµÎñÂß¼­¡£

±¾ÆªÖ»ÊÇʹÓÃAOPµÄÈÈÉí£¬Èç¹ûÕâÊÇÄã³õ´Î½Ó´¥AOP£¨²»Ì«¿ÉÄÜ£©£¬ÄÇôÄãÒѾ­×ßÉÏÁ˹¹½¨¸üºÃ¡¢¸üÁé»î¡¢¸üÈÝÒ×ÔĶÁºÍά»¤µÄÈí¼þ֮·¡£

   
4109 ´Îä¯ÀÀ       28
 
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
 
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
 
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì