web-dev-qa-db-ja.com

私のクラスはSOLIDの単一責任原則に違反していますか?

聞きたいのは:

  1. ロールクラスがSOLID?

  2. ロールとアカウントにdeleteAccount()があります。それは大丈夫です ?

  3. 管理者およびモデレート違反DRY原則?deleteAccount()が繰り返されたため。そうである場合、それを修正する方法?

  4. 自分自身のアカウントを削除できるdeleteAccount()を実装する方法は?それを行うには、戦略設計パターンを使用する必要がありますか?

     class Account:
        def __init__(self, email, password, security_ans):
            self.status = "Active"
            self.role = Member()
    
    
        def deleteAccount(self, dest_email):
            dest_account = accounts.getByEmail(dest_email) #get account obj from accounts 
            self.role.deleteAccount(self)
    

これは私のRoleクラスです:

class Role:
def blockAccount(self, account):
    raise NotImplementedError("No Permission")

class Admin(Role):
    def deleteAccount(self, account_obj):
        account_obj.setStatus('Closed')

class Moderator(Role):
    def deleteAccount(self, account_obj):
        account_obj.setStatus('Closed')

class Member(Role):
    def deleteAccount(self, account_obj):
        raise NotImplementedError("No Permission") 
3
Nguyen Nguyen

はい、あなたのRoleクラスは、アカウントを削除する知識howを持っているため、単一責任の原則に違反しています。その知識は、Accountクラス自体に予約する必要があります。

Roleクラスに属する知識は、特定のロールを持つユーザーが削除を許可されているアカウントです。また、1人のユーザーが異なる役割を持つことができます。

たとえば、Roleは次のように権限を処理できます。

class Role:
  def canDeleteAccount(self, requester, target):
    return False

class Admin(Role):
  def canDeleteAccount(self, requester, target):
    # Admins can delete anyone
    return True 

class Moderator(Role):
  def canDeleteAccount(self, requester, target):
    # Moderators can only delete Members, not Admins or other Moderators
    return target.is_only_member()

class Member(Role):
  def canDeleteAccount(self, requester, target):
    # Members can only delete themselves
    return requester == target

アカウント自体のアカウント削除ロジックは次のようになります

class Account:
  def deleteAccount(self, dest_email, hard_delete=False):
    dest_account = accounts.getByEmail(dest_email) #get account obj from accounts
    can_delete = any(role.canDeleteAccount(self, dest_account) for role in self.roles)
    if can_delete:
      if hard_delete and (Admin in self.roles or dest_account.reputation() < hard_delete_threshold):
        accounts.delete(dest_account)
      else:
        dest_account.setStatus("Closed") 

評判の低いアカウントの完全削除(データベースからの削除)を許可するように、または管理者ロールを持つユーザーが削除を行う場合は、削除ロジックを拡張したことに注意してください。ハード削除とソフト削除の区別は、Roleクラスでは表示されません。

また、モデレーターAは、そのユーザーがメンバーロールも持っている場合、自分自身を削除できることに注意してください。

ロールはアクターではなくプロパティであるため、DeleteAccountはどの例にも含めないでください。役割には、それに関連付けられた一連の権利があります。これは便利な機能であり、ユーザーに一連の権利を割り当てることができます。これらの権利があれば、その人は削除操作を開始することを許可または禁止されます。削除操作自体は、アカウントを作成、変更、削除できるAccountManagerクラスのメソッドである必要があります。

あなたの主な問題はあなたが人としての役割を考えていることです。彼らはそうではありません、それでもメンバークラスが必要です。メンバーを保持し、役割の子孫にしないで、代わりに役割のリストをプロパティとしてメンバーに追加します。

4
Martin Maat