Verknüpfen von Themen, Klassifizieren der Beziehung als Ursache, Wirkung, Obermenge usw

  • Ich sah dieses gigantische If zum ersten Mal und versuchte es zu überarbeiten. Kann nur mit einer endlosen switch-Anweisung enden.

    Alter Code -

       # It is a Cause
        if @causality == "C"  
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @notice = 'New cause linked Successfully'
        end
    
        # It is an Inhibitor
        if @causality == "I"  
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @relationship.relationship_type = 'I'
          @notice = 'New reducing issue linked Successfully'
        end        
    
        # It is a Superset
        if @causality == "P"  
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @relationship.relationship_type = 'H'
          @notice = 'New superset linked Successfully'
        end
    
        # It is an Effect
        if @causality == "E"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid      
          @notice = 'New effect linked Successfully'
        end
    
        # It is an Inhibited
        if @causality == "R"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid      
          @relationship.relationship_type = 'I'
          @notice = 'New reduced issue linked Successfully'
        end
    
        # It is a Subset
        if @causality == "S"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid
          @relationship.relationship_type = 'H'          
          @notice = 'New subset linked Successfully'
        end 
     

    Das ist auf einer Seite des Falls, wenn auf der "Anderen" -Seite ein ähnlicher Code so aussieht

      # Populate User_Id if relationship was created by a logged in User
          if @issue.user_id.to_s != ""
            @relationship.user_id = @issue.user_id  
          end
    
          # It is a Cause
          if @causality == "C"  
            @relationship.cause_id = @issue.id
            @relationship.issue_id = @causality_id          
            @notice = 'New Issue was created and linked as a cause'
          end
    
          # It is an Inhibitor
          if @causality == "I"  
            @relationship.cause_id = @issue.id
            @relationship.issue_id = @causality_id
            @relationship.relationship_type = 'I'            
            @notice = 'New Issue was created and linked as reducer'
          end
    
          # It is a Superset
          if @causality == "P"  
            @relationship.cause_id = @issue.id
            @relationship.issue_id = @causality_id 
            @relationship.relationship_type = 'H'
            @notice = 'New Issue was created and linked as a superset'
          end         
    
          # It is an Effect
          if @causality == "E"  
            @relationship.cause_id = @causality_id
            @relationship.issue_id = @issue.id
            @notice = 'New Issue was created and linked as an effect'
          end          
    
          # It is an Inhibited
          if @causality == "R"  
            @relationship.cause_id = @causality_id
            @relationship.issue_id = @issue.id
            @relationship.relationship_type = 'I'
            @notice = 'New Issue was created and linked as reduced'
          end              
    
          # It is a Subset
          if @causality == "S"  
            @relationship.cause_id = @causality_id
            @relationship.issue_id = @issue.id
            @relationship.relationship_type = 'H'
            @notice = 'New Issue was created and linked as a subset'
          end  
     

    Neuer Code -

     def set_type_of_relationship(already_exists)
      if !already_exists
        case @causality
        when "C"       
          @relationship.cause_id = @issue.id
          @relationship.issue_id = @causality_id  
          @notice = 'New Issue was created and linked as a cause'
        when "I"
          @relationship.cause_id = @issue.id
          @relationship.issue_id = @causality_id  
          @relationship.relationship_type = 'I'            
          @notice = 'New Issue was created and linked as reducer'
        when "P"
          @relationship.cause_id = @issue.id
          @relationship.issue_id = @causality_id  
          @relationship.relationship_type = 'H'
          @notice = 'New Issue was created and linked as a superset'
        when "E"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issue.id
          @notice = 'New Issue was created and linked as an effect'
        when "R"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issue.id
          @relationship.relationship_type = 'I'
          @notice = 'New Issue was created and linked as reduced'
        when "S"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issue.id
          @relationship.relationship_type = 'H'
          @notice = 'New Issue was created and linked as a subset'
        else 
          @notice = 'Error creating and linking issue'
        end
      else #if already_exists
        case @causality
        when "C"       
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @notice = 'New cause linked Successfully'
        when "I"
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @relationship.relationship_type = 'I'
          @notice = 'New reducing issue linked Successfully'
        when "P"
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id
          @relationship.relationship_type = 'H'
          @notice = 'New superset linked Successfully'
        when "E"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid      
          @notice = 'New effect linked Successfully'
        when "R"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid      
          @relationship.relationship_type = 'I'
          @notice = 'New reduced issue linked Successfully'
        when "S"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid
          @relationship.relationship_type = 'H'          
          @notice = 'New subset linked Successfully'
        else 
          @notice = 'Error creating and linking issue'
        end 
      end
    end
     

    Diese endlose Switch-Anweisung (case) hat mich etwas verrückt gemacht Ich fand jedoch keine Möglichkeit, die enorme Liste von ifs in etwas einfacher zu debuggen und, was noch wichtiger ist, mit weniger Duplizierungen. Ich habe mich entschieden, alles in zwei Switches zu extrahieren, hauptsächlich weil Switches mit einer indizierten Verzweigungstabelle in Ruby implementiert sind - d. H. Sehen Sie sich das hier genauer an und helfen Sie mir, es neu zu formulieren!

    Achtung: Achten Sie auf die Unterschiede zwischen

    @relationship.cause_id = @issueid @relationship.issue_id = @causality_id

    und

    @relationship.cause_id = @causality_id @relationship.issue_id = @issue.id
    12 January 2017
    200_successAsik
3 answers
  • Ich würde eigentlich eher objektorientiert vorgehen. Angenommen, Ihr ursprüngliches Objekt (das Sie für den Zugriff auf die Attribute @relationship und @causality verwenden) heißt OriginalObject. In der Realität könnte dies ein Controller oder ein einfaches Ruby-Objekt sein.

     class OriginalObject
      attr_accessor :issue, :causality_id, :issueid
    
      def set_type_of_relationship(already_exists)
        obj = causality_object(already_exists)
    
        if obj.nil?
          @notice = 'Error creating and linking issue'
          return
        end
    
        @relationship.cause_id = obj.cause_id(self)
        @relationship.issue_id = obj.issue_id(self)
        @relationship.relationship_type = obj.relationship_type
        @notice = obj.notice
      end
    
      private
    
      def causality_object(already_exists)
        case @causality
        when 'C' then Cause
        when 'I' then Inhibitor
        when 'E' then Effect
        ...
        else nil
        end.new(already_exists)
      end
    end
     

    Ich würde dann jedes Objekt entfernen, das das Objekt entfernt die Bedingungen und vereinfachen Sie den Code:

     class CauseObject
      def initialize(already_exists)
        @already_exists = already_exists
      end
    
      def notice(created_and_linked, linked)
        if @already_exists
          "New Issue was created and linked as #{created_and_linked}"
        else
          "New #{linked} linked Successfully"
        end
      end
    end
    
    class CIPCauseObject < CauseObject
      def cause_id(obj)
        @already_exists ? obj.issueid : obj.issue.id
      end
    
      def issue_id(obj)
        obj.causality_id
      end
    end
    
    class ERSCauseObject < CauseObject
      def cause_id(obj)
        obj.causality_id
      end
    
      def issue_id(obj)
        @already_exists ? obj.issueid : obj.issue.id
      end
    end
     

    Dies würde das Erstellen neuer Cause, Effect, Inhibitor usw. Objekte.

     class Cause < CIPCauseObject
      def relationship_type; nil; end
    
      def notice
        super('a cause', 'cause')
      end
    end
    
    class Inhibitor < CIPCauseObject
      def relationship_type; 'I'; end
    
      def notice
        super('a reducer', 'reducer')
      end
    end
    
    class Effect < ERSCauseObject
      def relationship_type; nil; end
    
      def notice
        super('an effect', 'effect')
      end
    end
     

    Dieser Ansatz ermöglicht die Erweiterung weiterer Funktionen auf dem verursachen Objekte, ohne dass die ursprüngliche Bedingung erneut geschrieben werden muss. Beispielsweise kann die Antwort der Benachrichtigung geändert werden, ohne dass die ursprüngliche Nachrichtenformatierung angepasst werden muss. Es ist auch einfacher, diesen Code isoliert zu testen. Meines Erachtens ist die Funktion set_type_of_relationship auch viel einfacher zu lesen, da in ihr keine großen und verwirrenden Bedingungen mehr vorhanden sind.

    05 December 2011
    Lukecrashmstr
  • Dieses Stück hier:

     if already_exists
      case @causality 
      when "C", "I", "P"
      @relationship.cause_id = @issueid
      @relationship.issue_id = @causality_id 
      when "E", "R", "S"
      @relationship.cause_id = @causality_id
      @relationship.issue_id = @issueid
      end   
      @relationship.relationship_type = args[0].try(:to_s)            
    else
      case @causality 
      when "C", "I", "P"
      @relationship.cause_id = @issue.id
      @relationship.issue_id = @causality_id 
      when "E", "R", "S"
      @relationship.cause_id = @causality_id
      @relationship.issue_id = @issue.id
      end
      @relationship.relationship_type = args[0].try(:to_s)            
    end
     

    Ist dies:

     issue_id = already_exists ? @issueid : @issue.id
    ids = [issue_id, @causality_id]
    ids.rotate! if %W[E R S].member? @causality
    @relationship.cause_id, @relationship.issue_id = ids
    @relationship.relationship_type = args[0].try(:to_s)            
     

    (Ungetestet, aber ziemlich nah dran.)

    Als ein Punkt von Interesse war dies hier der mittlere Schritt zwischen den beiden.

     if already_exists
      vars = [@issueid, @causality_id]
      vars.rotate! if %W[E R S].member? @causality
      @relationship.cause_id, @relationship.issue_id = vars
    else
      vars = [@issue.id, @causality_id]
      vars.rotate! if %W[E R S].member? @causality
      @relationship.cause_id, @relationship.issue_id = vars
    end
    # Don't know why you repeated this.
    @relationship.relationship_type = args[0].try(:to_s)            
     

    Für mich laufen diese Dinge in Stufen ab. Das erste, was mir auffiel, war, dass die Logik der beiden Brocken identisch war, nur mit unterschiedlichen Werten. In meinem Kopf:

    • Jeder Block verwendet andere Werte
    • Nur einer ist anders
    • @causality lässt sie umkehren
    • Ruby kann dies auf einfache Weise ausdrücken
    06 December 2011
    xbonez
  • Ok, ich bin der Autor der Frage, aber ich habe keinen Bericht zu CR, dies ist das letzte Refactoring:

     def set_type_of_relationship(already_exists)
        args = { 
            C: [nil, 'a cause',    'cause'],
            I: [:I,  'a reducer',  'reducer issue'],
            P: [:H,  'a superset', 'superset'],
            E: [nil, 'an effect',  'effect'],
            R: [:I,  'reduced',    'reduced issue'],
            S: [:H,  'a subset',   'subset'] 
          }[@causality.to_sym]
    
        (@notice = 'Error creating and linking issue' and return) if args.nil?
    
        if already_exists
          case @causality 
          when "C", "I", "P"
          @relationship.cause_id = @issueid
          @relationship.issue_id = @causality_id 
          when "E", "R", "S"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issueid
          end   
          @relationship.relationship_type = args[0].try(:to_s)            
        else
          case @causality 
          when "C", "I", "P"
          @relationship.cause_id = @issue.id
          @relationship.issue_id = @causality_id 
          when "E", "R", "S"
          @relationship.cause_id = @causality_id
          @relationship.issue_id = @issue.id
          end
          @relationship.relationship_type = args[0].try(:to_s)            
        end
    
        @notice = if already_exists
                    "New Issue was created and linked as #{args[1]}"
                  else
                    "New #{args[2]} linked Successfully"
                  end
      end  
     
    05 December 2011
    eLobato