/// <summary>
        /// Here we have an application used to conduct market and sales research at our
        /// local farmer's market. As part of our efforts to improve the services we provide
        /// at the farmer's market, we need to aggregate sales and demographic data already collected
        /// by our vendors.
        /// Each class of vendor has different means of collecting its data, and we want to write
        /// an extensible way to aggregate and report on this data without modifying each class to
        /// write custom research reports.  This would help us write more extensible code (Open/Closed principle)
        /// and keep us from adding unwanted responsibility to the data processing classes
        /// (Single Responsibility principle).
        /// We can leverage the Visitor Pattern, where we make our data processing classes "visitable"
        /// by anything that generates a Report.  Then, we can create individual Visitor classes that
        /// generate their own specific types of reports.
        /// If a processor doesn't provide the data we need for a particular report, we can handle that
        /// logic altogether differently, perhaps notifying the stakeholders that we can't access this data
        /// for reporting purposes.
        /// </summary>
        private static void Main()
        {
            var logger          = new ConsoleLogger();
            var emailer         = new Emailer(logger);
            var farmDatabase    = new Database(Configuration.ConnectionString, logger);
            var floristDatabase = new Database(Configuration.ConnectionString, logger);
            var bakeryDatabase  = new Database(Configuration.ConnectionString, logger);

            logger.LogInfo("🌾 Welcome to the Farmer's Market Research Application!");
            logger.LogInfo("-------------------------------------------------------");

            // Various existing components know how to produce the data we need
            // But we don't want to modify them to add new responsibilities, like
            // generating reports.  We make these Visitable, so that a Visitor
            // can use them as it needs.
            var bakeryDataProcessor  = new BakeryDataProcessor(emailer, bakeryDatabase);
            var farmerDataProcessor  = new FarmerDataProcessor(farmDatabase);
            var floristDataProcessor = new FloristDataProcessor(emailer, floristDatabase);

            var dataProcessors = new List <IVisitable <Report> > {
                bakeryDataProcessor,
                farmerDataProcessor,
                floristDataProcessor
            };

            var reporter = new ReportRunner(logger);

            logger.LogInfo("==== Generating Sales Reports ====");
            reporter.RunReports(dataProcessors, new SaleDataVisitor(logger));

            logger.LogInfo("==== Generating Market Reports ====");
            reporter.RunReports(dataProcessors, new MarketResearchReportVisitor(logger));
        }
예제 #2
0
        public SalesReport Visit(FarmerDataProcessor processor)
        {
            Console.ForegroundColor = ConsoleColor.Magenta;
            _logger.LogInfo("Visiting Farmer for Sales Report");
            var sales = processor.GetDailyOrderAmounts();

            Console.ResetColor();
            return(new SalesReport(_logger, DateTime.UtcNow, sales.Sum()));
        }
예제 #3
0
 public MarketResearchReport Visit(FarmerDataProcessor order)
 {
     _logger.LogDebug("Market research is not yet available for Farm Data");
     return(null);
 }