Вот вариант
library(tidyverse)
data %>%
gather(key, val, -query_name, -match_name) %>%
select(-match_name, -key) %>%
group_by(query_name, val) %>%
add_count() %>%
group_by(query_name) %>%
filter(n == max(n)) %>%
summarise(location_output = paste0(unique(val[!is.na(val)]), collapse = ";"))
## A tibble: 3 x 2
# query_name location_output
# <fct> <chr>
#1 feature1 NorthAmerica;UnitedStates;NewYork
#2 feature2 NorthAmerica;Canada
#3 feature3 Europe;Germany
Конечно, это совершенно разумно. В основном то, что вы сделали, очень похоже на фабричный шаблон. Я не вижу никаких проблем с этим, поскольку ваш код, по-видимому, подразумевает, что каждый объект Software должен иметь указатель на своего создателя.
Хотя обычно вы можете избежать использования классов «Manager», таких как SoftwareProducer, и просто иметь статические методы в Software. Так как кажется вероятным, что будет только один SoftwareProducer. Возможно, что-то вроде этого:
class Software {
private:
Software() : m_key(0) { /* whatever */ }
public:
void buy() { m_key = new_key(); }
public:
static Software *create() { return new Software; }
private:
static int new_key() { static int example_id = 1; return example_id++; }
private:
int m_key;
};
Тогда вы можете просто сделать это:
Software *soft = Software::create();
soft->buy();
Конечно, если вы планируете иметь более одного объекта SoftwareProducer, то то, что вы сделали, кажется уместным.
Мне это кажется вполне разумным.
Ознакомьтесь с Фабрики: инкапсуляция создания объекта из Брюс Экель «Размышление на С ++» для получения дополнительной информации об этом конкретном использовании друзей.
Вы также можете взглянуть на FAQ по C ++ для друзей , чтобы ознакомиться с некоторыми практическими правилами.
I think making SoftwareProducer as a friend of Software is acceptable but I see no reason why Software has to be the friend of SoftwareProducer class. It is an unnecessary dependency between them. You can take key as a constructor argument for the Software class. Also you might want to make the destructor of Software class private so that nobody except the SoftwareProducer can destroy them.
Я не буду обсуждать вопрос дружбы, но мне не нравятся циклические зависимости. Программное обеспечение зависит от SoftwareProducer, который сам зависит от программного обеспечения ... Я попытался бы провести рефакторинг.
Также обратите внимание, что дружеские отношения открывают внутренние компоненты для всех экземпляров другого класса. Это то же самое, что сказать, что ваш комментарий в next_key неверен:
Если next_key закрытым, запрещается вызывать его у любого класса, но как только вы открываете для Software , любое программное обеспечение может вызывать next_key на всех SoftwareProducers .