디자인 모드 - 구조에 관한 모드

15271 단어 Ruby

Adapter


개요


기존 카테고리의 출력 또는 인터페이스를 원하는 형식으로 변환

예:


IPhone 정보를 출력하는 렌더링 클래스
렌더 클래스를 사용하여 안드로이드 정보를 출력하려면
  • IPhone(Adaptee)
  • AndroidAdapter(Adapter)
  • Android(Client)
  • 장점


    어댑터를 만들면 안드로이드, 아이폰류 어느 것도 수정할 필요 없어

    방법1


    위탁을 통해 실현하다
    아이폰의 개체를 Android 어댑터에 저장
    class Render 
      def render(text_object) 
        @text = text_object.text
        @size = text_object.size_cm
        @color = text_object.color
        printData
      end
    
      private
        def printData
          puts @text
          puts "#{@size} cm"
          puts @color
        end
    end
    
    class IPhone
      attr_reader :text, :size_cm, :color
    
      def initialize(text, size_cm, color)
        @text = text
        @size_cm = size_cm
        @color = color
      end
    end
    
    class Android
      attr_reader :string, :size_mm, :type
    
      def initialize(string, size_mm, type)
        @string = string
        @size_mm = size_mm
        @type = type
      end
    end
    
    class AndroidAdapter
      def initialize(android)
        @android = android
      end
    
      def text
        @android.string
      end
    
      def size_cm
        @android.size_mm / 1000
      end
    
      def color
        @android.type
      end
    end
    
    iphone = IPhone.new("This is IPhone", 12, "red")
    android = Android.new("This is android", 15000, "black")
    fixed_android = AndroidAdapter.new(android)
    
    render_object = Render.new
    p "---IPhone---"
    render_object.render(iphone)
    p "---Android---"
    render_object.render(fixed_android)
    

    방법2


    상속을 통해 실현하다
    Android에서 새 인터페이스 설명
    android = Android.new("This is android", 15000, "black")
    
    class << android
      def color
        type
      end
    
      def text
        string
      end
    
      def size_cm
          size = size_mm / 1000
          "#{size} cm"
      end
    end
    
    render_object = Render.new
    p "---Android---"
    p android.text
    p android.size_cm
    p android.color
    

    Composite


    개요


    파일 시스템 등 귀속 데이터 구조의 표시를 간소화하다
    요소를 그것들과 함께 관리하는 방법은 비슷한 방법이 있는데, 그것들을 모두 똑같이 처리하고 싶을 때

    예제

    # 共通メソッドを規定(Component)
    class Entry
      def get_name; end
      def ls(prefix) end
      def remove; end
    end
    
    # 単純な構成要素、再帰しない(Leaf)
    class FileClass < Entry
      def initialize(name)
        @name = name
      end
      def get_name
        @name
      end
      def ls(prefix)
        puts(prefix + "/" + get_name)
      end
      def remove
        puts "Removed " + @name + " file"
      end
    end
    
    # 再帰する(Composite)
    class DirClass < Entry
      def initialize(name)
        @name = name
        @directory = Array.new
      end
      def get_name
        @name
      end
      # ディレクトリにディレクトリ/ファイルを追加する
      def add(entry)
        @directory.push(entry)
      end
      # ファイル/ディレクトリのパスを返す
      def ls(prefix)
        puts(prefix + "/" + get_name)
        @directory.each do |element|
          element.ls(prefix + "/" + @name)
        end
      end
      def remove
        @directory.each do |element|
          element.remove
        end
        puts "Removed " + @name + " directory"
      end
    end
    
    root = DirClass.new("rootDir")
    tmp = DirClass.new("tmpDir")
    tmp.add(FileClass.new("confFile"))
    tmp.add(DirClass.new("dataDir"))
    root.add(tmp)
    
    root.ls("")
    # /rootDir
    # /rootDir/tmpDir
    # /rootDir/tmpDir/confFile
    # /rootDir/tmpDir/dataDir
    
    root.remove
    # Removed confFile file
    # Removed dataDir directory
    # Removed tmpDir directory
    # Removed rootDir directory
    

    Decorator


    개요


    기존 객체에 대한 단순 추가 기능
    기존 객체 수정 안 함

    예제

    require 'forwardable'
    # ConcreteComponent
    class SimpleWriter
      def initialize(path)
        @file = File.open(path, 'w')
      end
      def write_line(line)
        @file.print(line)
        @file.print('\n')
      end
      # ファイル出力位置
      def pos
        @file.pos
      end
      def rewind
        @file.rewind
      end
      def close
        @file.close
      end
    end
    # Decorator(共通部分)
    class WriterDecorator
      extend Forwardable
      def_delegators :@real_writer, :write_line, :pos, :rewind, :close
      def initialize(real_writer)
        @real_writer = real_writer
      end
    end
    # Decorator
    module NumberingWriter
      attr_reader :line_number
    
      def write_line(line)
        @line_number = 1 unless @line_number
        super("#{@line_number} : #{line}")
        @line_number += 1
      end
    end
    # Decorator
    module TimeStampingWriter
      def write_line(line)
        super("#{Time.new} : #{line}")
      end
    end
    
    f = SimpleWriter.new('88.txt')
    f.extend TimeStampingWriter
    f.extend NumberingWriter
    f.write_line('Hello out there')
    f.close
    

    Proxy


    개요


    프로그램 주체의 클래스 앞에서 다른 클래스를 물고 데이터 액세스 자체와 그 부수적인 처리를 분리한다

    예제

    class RealObject
      attr_accessor :secret_info
      def initialize(secret_info)
        @secret_info = secret_info
      end
    end
    
    class Proxy
      attr_accessor :real_object
      def initialize(real_object)
        @real_object = real_object
      end
      def secret_info
        print "warning use secret_infoz\n"
        return @real_object.secret_info
      end
    end
    
    p = Proxy.new(RealObject.new("secret"))
    print p.secret_info
    

    좋은 웹페이지 즐겨찾기