Questo è un esempio di schema o algoritmo?

1

Mi sento come se avessi un "qualcosa" riutilizzabile qui e non sono sicuro se pensarlo come un pattern o un algoritmo (o nessuno dei due).

È caratterizzato dall'avere una quantità sconosciuta di lavoro per portare a termine un'attività perché le sottoattività possono incontrare varie condizioni che causano l'aggiunta di "Problemi" a una coda globale.

Quindi, il comando viene eseguito ripetutamente accoppiato con un round di "Issue Fixing" fino a quando non ci sono problemi o il numero di problemi non cambia.

Sto solo mettendo abbastanza codice qui per mostrare di cosa sto parlando - c'è un po 'di più (fammi sapere se dovrei postare di più)

        public void FindNewCampaigns()
        {
            var findNewCampaigns = Locator.Get<ICommand<IEnumerable<Campaign>>>("FindNewCampaigns");
            var campaigns = findNewCampaigns.Execute();
            var issues = Locator.Get<ICollection<Issue>>("CommandIssues");
            while (issues.Count > 0)
            {
                int before = issues.Count;
                FixIssues(issues);
                issues.Clear();
                campaigns = findNewCampaigns.Execute();
                int after = issues.Count;
                if (before == after)
                {
                    System.Console.WriteLine("No issues got fixed, quitting ({0}/{1}).", before, after);
                    break;
                }
            }
            if (issues.Count == 0)
            {
                CreateCampaigns(campaigns);
            }
        }

        private void FixIssues(ICollection<Issues.Issue> issues)
        {
            foreach (var issue in issues)
            {
                System.Console.WriteLine("ISSUE: " + issue.GetType().Name + " - " + issue.ToString());

                if (issue is AdvertiserDoesNotExist)
                {
                    var specificIssue = (AdvertiserDoesNotExist)issue;
                    var command = Locator.Get<ICommand<string, DirectAgents.SynchService.Model.EomDatabase.Advertiser>>("CreateAdvertiser");
                    command.Execute(specificIssue.AdvertiserName);
                }
                else if (issue is AccountManagerDoesNotExist)
                {
                    var specificIssue = (AccountManagerDoesNotExist)issue;
                    var command = Locator.Get<ICommand<string, DirectAgents.SynchService.Model.EomDatabase.AccountManager>>("CreateAccountManager");
                    command.Execute(specificIssue.AccountManagerName);
                }
                else if (issue is AdManagerDoesNotExist)
                {
                    var specificIssue = (AdManagerDoesNotExist)issue;
                    var command = Locator.Get<ICommand<string, DirectAgents.SynchService.Model.EomDatabase.AdManager>>("CreateAdManager");
                    command.Execute(specificIssue.AdManagerName);
                }
                else if (issue is MediaBuyerDoesNotExist)
                {
                    var specificIssue = (MediaBuyerDoesNotExist)issue;
                    var command = Locator.Get<ICommand<string, DirectAgents.SynchService.Model.EomDatabase.MediaBuyer>>("CreateMediaBuyer");
                    command.Execute(specificIssue.MediaBuyerName);
                }
            }
        }

Ecco il codice per FindNewCampaigns . Aggiunge problemi mentre li trova. Un numero dovrebbe essere qualcosa che deve accadere prima che una nuova campagna possa effettivamente essere creata in un negozio di destinazione.

    public class FindNewCampaigns : Command<IEnumerable<Campaign>>
    {
        private IFactory<CakeEntities> cakeEntities;
        private IFactory<DADatabase> eomDatabase;

        public FindNewCampaigns(IFactory<CakeEntities> cakeEntities, IFactory<DADatabase> eomDatabase)
        {
            this.cakeEntities = cakeEntities;
            this.eomDatabase = eomDatabase;
        }

        public override IEnumerable<Campaign> Execute()
        {
            using (var eom = eomDatabase.Create())
            using (var cake = cakeEntities.Create())
            {
                // Get EOM campaigns
                var campaigns = eom.Campaigns.Select(c => c.pid).ToList();
                // Get Cake offers
                var offers = cake.CakeOffers.Select(c => c.Offer_Id).ToList();
                // Get Cake offers that don't match to EOM campaigns
                var newOffers = offers.Except(campaigns).ToList();
                // Get default values
                int accountManagerID = DefaultAccountManagerId(eom);
                int adManagerID = DefaultAdManagerId(eom);
                int advertiserID = DefaultAdvertiserID(eom);
                int campaignStatusID = DefaultCampaignStatus(eom);
                // Create new campaigns in memory
                var newCampaigns = (from offer in cake.CakeOffers
                                    where newOffers.Contains(offer.Offer_Id)
                                    select new
                                    {
                                        Offer = offer,
                                        Campaign = new Campaign {
                                            pid = offer.Offer_Id,
                                            campaign_name = offer.OfferName,
                                            campaign_status_id = campaignStatusID,
                                            account_manager_id = accountManagerID,
                                            ad_manager_id = adManagerID,
                                            advertiser_id = advertiserID,
                                        }
                                    }).ToList();
                // Set campaign status
                var campaignStatus = eom.CampaignStatus.ToDictionary(c => c.name, c => c.id);
                campaignStatus.Add("Private", campaignStatus["Active"]);
                campaignStatus.Add("Apply To Run", campaignStatus["Active"]);
                campaignStatus.Add("Inactive", campaignStatus["default"]);
                foreach (var item in newCampaigns)
                {
                    string statusName = item.Offer.StatusName;
                    if (campaignStatus.ContainsKey(statusName))
                    {
                        item.Campaign.campaign_status_id = campaignStatus[statusName];
                    }
                    else
                    {
                        AddIssue(new CampaignStatusDoesNotExist(statusName));
                    }
                }
                // Set advertiser
                var cakeAdvertisers = cake.CakeAdvertisers.ToDictionary(c => c.Advertiser_Id);
                foreach (var item in newCampaigns)
                {
                    int offerAdvertiserID = int.Parse(item.Offer.Advertiser_Id);
                    var offerAdvertiser = cake.CakeAdvertisers.FirstOrDefault(c => c.Advertiser_Id == offerAdvertiserID);
                    string offerAdvertiserName = offerAdvertiser.AdvertiserName;
                    var eomAdvertiser = eom.Advertisers.FirstOrDefault(c => c.name == offerAdvertiserName);
                    if (eomAdvertiser != null)
                    {
                        item.Campaign.advertiser_id = eomAdvertiser.id;
                    }
                    else
                    {
                        AddIssue(new AdvertiserDoesNotExist(offerAdvertiserName));
                    }
                }
                // Set account manager
                foreach (var item in newCampaigns)
                {
                    int offerAdvertiserID = int.Parse(item.Offer.Advertiser_Id);
                    var offerAdvertiser = cake.CakeAdvertisers.FirstOrDefault(c => c.Advertiser_Id == offerAdvertiserID);
                    string offerAccountManager = offerAdvertiser.AccountManagerName;
                    if (offerAccountManager != null)
                    {
                        AccountManager am = eom.AccountManagers.ToList().SingleOrDefault(c => c.NameIsEquivalentTo(offerAccountManager));
                        if (am != null)
                        {
                            item.Campaign.account_manager_id = am.id;
                        }
                        else
                        {
                            AddIssue(new AccountManagerDoesNotExist(offerAccountManager));
                        }
                    }
                    else
                    {
                        AddIssue(new OfferHasNoAccountManager(item.Offer.OfferName));
                    }
                }
                // Set ad manager
                foreach (var item in newCampaigns)
                {
                    int offerAdvertiserID = int.Parse(item.Offer.Advertiser_Id);
                    var offerAdvertiser = cake.CakeAdvertisers.FirstOrDefault(c => c.Advertiser_Id == offerAdvertiserID);
                    string offerAdManager = offerAdvertiser.AdManagerName;
                    if (offerAdManager != null)
                    {
                        AdManager ad = eom.AdManagers.ToList().SingleOrDefault(c => c.NameIsEquivalentTo(offerAdManager));
                        if (ad != null)
                        {
                            item.Campaign.ad_manager_id = ad.id;
                        }
                        else
                        {
                            AddIssue(new AdManagerDoesNotExist(offerAdManager));
                        }
                    }
                    else
                    {
                        AddIssue(new OfferHasNoAdManager(item.Offer.OfferName));
                    }
                }
                return newCampaigns.Select(c => c.Campaign).ToList();
            }
        }
    
posta Aaron Anodide 17.05.2012 - 04:13
fonte

3 risposte

2
Is this an example of a pattern or an algorithm?

È un algoritmo.

Un modello è un approccio generalizzato / portatile alla risoluzione di un problema. Un algoritmo è un approccio specifico per risolvere un problema.

Vedi questa domanda SO: link

    
risposta data 17.05.2012 - 19:13
fonte
2

Non sei sicuro di quale risposta stai cercando, ma il codice sembra implementare una coda di lavoro base. Immagino che questo si ridurrà di più nella categoria algoritmo . C'è un sacco di codice là fuori che implementa un'idea simile, ma penso che sia troppo semplice dichiarare "riutilizzabile". Il sovraccarico dovuto alla gestione di questo codice potrebbe superare il suo valore di utilizzo in più posizioni.

L'unico problema con il codice sopra (credo che questo ricadrebbe sotto la revisione del codice piuttosto che i programmatori SE) è che non è molto riutilizzabile / estensibile finché il tuo metodo FixIssues () ha una lunga se-else se- else if-else if -... else if-else chain. Viola il principio open-close di OOD perché ogni volta che aggiungi un nuovo tipo di problema, devi tornare indietro e modificare la stessa funzione più e più volte. Ti suggerisco di utilizzare uno schema di fabbrica e di avere una classe esterna che decide quale comando istanziare per un dato tipo di problema. È possibile utilizzare la riflessione di .NET per evitare di dover creare log if-else chains (o istruzioni switch) e si aggiornerà in modo dinamico ogni volta che si aggiungono classi di comando / comando all'assembly, a patto di assegnare loro un attributo personalizzato univoco.

Dal punto di vista della chiarezza, mi aspetto un metodo chiamato "FindNewCampaigns" per fare tutto il lavoro necessario per trovare le nuove campagne e metterle in una sorta di collezione. Tuttavia, dopo aver letto i dettagli del codice, quel metodo sembra risolvere i problemi ?? quello non sembra essere la stessa cosa di "trovare", quindi forse un nome migliore sarebbe appropriato?

    
risposta data 17.05.2012 - 05:21
fonte
1

Penso che troverai questo tipo di algoritmi quando utilizzi google per parole chiave come invio eventi o coda eventi . Un sacco di sistemi basati su eventi hanno un tale ciclo nel suo nucleo.

L'unica differenza nel tuo caso è che in genere in tali sistemi i nuovi eventi possono anche provenire "dall'esterno" in modo asincrono.

    
risposta data 17.05.2012 - 12:18
fonte

Leggi altre domande sui tag