2017-01-26 6 views
0

Извиняется, если мой вопрос кажется тривиальным. Я только что вернулся в ООП после 15-летнего отсутствия, и я перехожу с Java на python. Я широко толкнул за четкий ответ, но никто не нашел. Pls перенаправляет меня, если ответ уже существует.Работа над классом, совместно используемым между основной программой и функцией

Я ищу советы по лучшей практике в отношении того, что я бы назвал глобальным или местным классом. Основная программа реального приложения, которое я разрабатываю, по-видимому, потребует около 4 основных классов (например, класс Register в прикрепленном макету), а основной класс, который создает системную сеть, будет иметь только один экземпляр. Каждый основной класс будет иметь различные атрибуты, включая вложенные классы, такие как Person, и эти вложенные классы будут использоваться только как таковые, т.е. никогда не вызываться для использования в качестве отдельных экземпляров.

В этом примере я вызываю newReg (мой «основной» класс) в качестве экземпляра Register. 'Используя последовательность 1', я вызываю 2 функции для ввода и вывода содержимого людей динамического массива. Я не передаю newReg как параметр для функций, потому что это единственный класс класса, который я планирую создать. Фактически, я использую функции как GOSUB ... RETURN подпрограммы (если кто-либо из вас когда-либо использовал BASIC), пытаясь развязать основную программу (проекты методов в моем реальном приложении до сих пор имеют много циклов и проверок и вложенных вызовов меню и я хочу сохранить их как блоки отдельно от основного потока логики программы). Однако это не похоже на ООП, но поскольку мне нужны только функции GOSUB ... ВОЗВРАЩАЕТСЯ в основной программе, это кажется прагматичным подходом. Но это хорошая практика?

Альтернативный вариант 2 последовательности передает newReg в качестве параметра для функций и, с соответствующим образом измененным функциям, я получаю тот же результат. Это больше похоже на ООП, но я не вижу преимущества этого, если только один экземпляр Register называется newReg. Фактически, если newReg стал очень большим, может быть накладные расходы на скорость для программы в передаче, воссоздании, передаче и уничтожении временного параметра класса в функции. Неужели эта накладная скорость не беспокоит?

Я мог бы быть еще больше ООП в случае более сложных классов и передавать только те параметры класса методу, который нуждается в обработке. Я начал с этого подхода, но вскоре кодирование стало беспорядочным и добавило дополнительный код в основной поток программы (извлечение данных из класса и вставку возвращаемых данных из функции обратно в класс), которые я хочу сохранить тощими и разборчивыми.

Должен ли я избегать использования моего предпочтительного варианта 1 и идти с опцией 2? Я пробовал вариант 3, но, похоже, он создает более сложное кодирование. Совет оценил.

class Register: 
    def __init__(self,dd,mm,yy): 
     self.d = dd 
     self.m = mm 
     self.y = yy 
     self.people = [] 

class Person: 
    def __init__(self,name,ident): 
     self.name = name 
     self.ident = ident 

def inputPeople(): 
    name ="" 
    print("enter 'end' as name to finish update") 
    while name != "end": 
     name = input("enter name:") 
     ID = input ("enter ID:") 
     if name == "end": 
      return 
     newperson = Person(name,ID) 
     newReg.people.append(newperson) 

def outputRegister(): 
    print("register date: %s/%s/%s" % (newReg.d, newReg.m, newReg.y)) 
    for element in newReg.people: 
     values = vars(element).values() 
     print('|'.join("%10s" % item for item in values)) 
    return 

#main prog option 1: treat newReg globally when calling functions 
newReg = Register(12,5,17) 
choice ="" 
while choice != "E": 
    choice = input("enter U to update, L to list, E to exit") 
    if choice == "U": 
     inputPeople() 
    if choice == "L": 
     outputRegister() 
print("session over") 

#main prog option 2: pass newReg as a parameter to the functions 
newReg = Register(12,5,17) 
choice ="" 
while choice != "E": 
    choice = input("enter U to update, L to list, E to exit") 
    if choice == "U": 
     newReg = inputPeople(newReg) # and modify fn codes accordingly 
    if choice == "L":   # to handle newReg as a parameter 
     outputRegister(newReg)# rather than a class object in 
print("session over")   # the main body 
+0

Возможно, вы захотите попробовать просить по адресу http: //codereview.stackexchange.com/ –

ответ

0

Поскольку оба варианта работают, это вопрос стиля и мнения, но мое личное мнение, что 1 это нормально для небольших скриптов, но улучшенный 2 является путь для больших приложений.

Ваша функция inputPeople() в обоих параметрах в значительной степени ограничена работой в экземпляре с полем людей, которое имеет интерфейс append. Это не идеально. С ООП было бы лучше, если бы у объекта, с которым вы проходили, был интерфейс для добавления людей, например, addPerson (Person).

Это будет означать, что ваша функция inputPeople не обязательно должна знать, что структура данных используется реестром для хранения людей. Также это облегчает повторное использование функции и передачу в других типах контейнеров людей, пока контейнер имеет метод AddPerson (Person).

С помощью опции 1 ваша функция inputPeople может использоваться только для newreg, а не для других вещей, которые также могут иметь людей.

+0

Привет, Алвин - ваш комментарий дал мне вдохновение. Я дал функцию в фактическом приложении, что я написал второй взгляд, и я думаю, что его можно переписать как 3 подфункции (с передачей параметров), каждая из которых может быть повторно использована в другом месте в будущем. Я более счастлив с этим пересмотренным подходом. Спасибо за ваше время и поделитесь своими мыслями. Это помогло! – Gary

+0

Спасибо, Гэри. Я начал изучать ООП, когда он все еще был взломан на Turbo Pascal 5, и долгое время я понимал структуру и набор функций ООП, но я пропустил важную часть ООП, а именно, как вы используете эту функцию для достижения целей, которые идут за пределами очевидного. Затем я прочитал первые образцы дизайна Bert Bates's Head, и хотя модели были аккуратными, меня действительно поразило то, как вы используете атрибуты OOP для достижения целей четкого кода и поддержания вашего кода в обслуживании и простоте повторного использования и расширения в одно и то же время. Ваши цели определяют ваш код и способы применения инструментов –

 Смежные вопросы

  • Нет связанных вопросов^_^