Pythonの「神オブジェクト」を作成してリファクタリングしたので、私は同情します。私がしたことは、メソッドに基づいて元のオブジェクトをサブセクションに分割することです。たとえば、元のコードは次の疑似コードのように見えました。
method A():
self.bla += 1
method B():
self.bla += 1
do stuff():
self.bla = 1
method A()
method B()
print self.bla
スタッフメソッドは、自己完結型の作業の「単位」です。オリジナルをインスタンス化する新しいクラスに移行しました。これにより、必要なプロパティも引き出されました。一部はサブクラスでのみ使用され、まっすぐに移動できました。他のものは共有され、共有クラスに移されました。
「Godオブジェクト」は、起動時に共有クラスの新しいコピーを作成し、新しいサブクラスのそれぞれは、initメソッドの一部としてポインターを受け入れます。たとえば、メーラーのストリップバージョンは次のとおりです。
#!/usr/bin/env python
# -*- coding: ascii -*-
'''Functions for emailing with dirMon.'''
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import os
import smtplib
import datetime
import logging
class mailer:
def __init__(self,SERVER="mail.server.com",FROM="support@server.com"):
self.server = SERVER
self.send_from = FROM
self.logger = logging.getLogger('dirMon.mailer')
def send_mail(self, send_to, subject, text, files=[]):
assert type(send_to)==list
assert type(files)==list
if self.logger.isEnabledFor(logging.DEBUG):
self.logger.debug(' '.join(("Sending email to:",' '.join(send_to))))
self.logger.debug(' '.join(("Subject:",subject)))
self.logger.debug(' '.join(("Text:",text)))
self.logger.debug(' '.join(("Files:",' '.join(files))))
msg = MIMEMultipart()
msg['From'] = self.send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach( MIMEText(text) )
for f in files:
part = MIMEBase('application', "octet-stream")
part.set_payload( open(f,"rb").read() )
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
msg.attach(part)
smtp = smtplib.SMTP(self.server)
mydict = smtp.sendmail(self.send_from, send_to, msg.as_string())
if self.logger.isEnabledFor(logging.DEBUG):
self.logger.debug("Email Successfully Sent!")
smtp.close()
return mydict
これは一度作成され、メーリング機能を必要とするさまざまなクラス間で共有されます。
したがって、larry
必要なプロパティとメソッドを含むクラスを作成します。クライアントが言うところはどこでもlarry = blah
それをに置き換えてくださいlarryObj.larry = blah
。これにより、現在のインターフェースを壊すことなく、サブプロジェクトに移行します。
他にすべきことは、「作業単位」を探すことだけです。「God Object」の一部を独自のメソッドに変換する場合は、そうします。ただし、メソッドをその外側に置きます。これにより、コンポーネント間のインターフェースを作成する必要があります。
その基礎を築くと、他のすべてがそれに続くことができます。たとえば、メイラーとのインターフェース方法を示すヘルパーオブジェクトの一部:
#!/usr/bin/env python
'''This module holds a class to spawn various subprocesses'''
import logging, os, subprocess, time, dateAdditionLib, datetime, re
class spawner:
def __init__(self, mailer):
self.logger = logging.getLogger('dirMon.spawner')
self.myMailer = mailer
可能な最小の個別作業単位に集中し、それを移動します。これは簡単に実行でき、セットアップをすばやく実行できます。ものを移動するためのプロパティを見てはいけません。ほとんどの場合、それらはそれらで実行されているタスクの補助的なものです。メソッドを処理した後に残ったものは、共有状態の一部であるため、おそらく元のオブジェクトにとどまるはずです。
ただし、新しいオブジェクトは必要なプロパティを初期変数として受け入れる必要があり、呼び出し元のオブジェクトのプロパティには触れません。次に、呼び出し側が必要に応じて共有プロパティを更新するために使用できる必要な値を返します。これはオブジェクトの分離に役立ち、より堅牢なシステムになります。