LINUX.ORG.RU

Интерфейс для плагинов в ООП

 , ,


0

3

Не могу разобраться как реализую подключение плагинов в основную программу.
В конечном варианте это должно выглядеть следующим образом:
Есть папка куда скидываются плагины, каждый плагин в отдельном файле, формат плагинов зарание определен.
Например:

class НазваниеПлагина 
  def plaginStart
    #куча кода
  end
end

Основная программа должна подгружать все классы(плагины) из этой папки, создавать объект каждого класса и выполнять функцию plaginStart. Название плагинов зарание не известно.

Расскажите как такое делать, желательно на руби но можно и java. Или пните в нужную сторону.

★★★★★

сильно не понял, что ты хочешь, но вообще на рубях ты сделаешь папку 'plugins' и сможешь сделать

require 'plugins/something'
DoctorSinus ★★★★★
()
Ответ на: комментарий от DoctorSinus

require это понятно, не понятно как создать объект класса с неизвестным названием.

TDrive ★★★★★
() автор топика

как реализую
Есть папка[отсутствующая запятая] куда скидываются плагины
зарание
не[ненужный_пробел]известно
желательно[отсутствующая запятая] на руби[отсутствующая запятая] но можно и [отсутствующее слово «на»] java.

OMG

Или пните в нужную сторону.

Кроме Розенталя потребуются разные другие книги.

stevejobs ★★★★☆
()

В Java можно загружать код в рантайме через ClassLoader.

mono ★★★★★
()

Ты хотя бы в гугл смотрел? Я не буду давать ссылку, она первая по вопросу, который ты задал, лентяй.

S-Mage ★★
()

Попробуй в лоб: напиши функцию, которая в цикле обходит все файлы в plugins/ и делает подключение каждого файла.

Dir.foreach('plugins') do |item|
  require "plugins/#{item}"
end
gwinn ★★★★
()
Последнее исправление: gwinn (всего исправлений: 1)
Ответ на: комментарий от O02eg

Не вопрос, я-то просто принцип описал, после require он может там же в цикле инстанс создавать для каждого плагина, топорно конечно, но до ума довести можно. А вообще: можно вот это вкурить, например.

gwinn ★★★★
()

Как насчет такого? http://stackoverflow.com/a/5441724

klass = "SomeNamespace::SomeClassName".constantize
klass.new

Dir["/path/to/directory/*.rb"].each do |file| 
  require file 
  file_name = File.basename(file.path, '.rb')
   # using ActiveSupport for camelcase and constantize
  file_name.camelcase.constantize.new 
end

// таки не рубист, но гугл помогает

rikardoac
()

Не задавался раньше таким вопросом, но можно объявить абстрактный класс Plugin и навешать на него хук inherited, который будет регистрировать дочерние классы:

config.rb:

class Configuration
  @@plugins = []

  def self.register(plugin)
    @@plugins << plugin
  end

  def self.start_plugins
    @@plugins.each do |plugin|
      plugin.new.start
    end
  end
end

class Plugin
  # Magic goes here!!!
  def self.inherited(subclass)
    Configuration.register subclass
  end

  def start
    raise NotImplementedError.new 'Should have been implemented in order to declare a plugin'
  end
end

Dir[File.dirname(__FILE__) + '/plugins/*.rb'].each { |f| require f}

Configuration.start_plugins

plugins/a.rb:

class A < Plugin
  def start
    puts "Hello, #{self.class}"
  end
end

plugins/b.rb:

class B < Plugin
  def start
    puts "Hello, #{self.class}"
  end
end

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)

inherited то что нужно, всем спасибо.

TDrive ★★★★★
() автор топика
Ответ на: комментарий от theNamelessOne

Еще не большой вопрос. почему

class Plugin
  def self.inherited(subclass)
    subclass.new.start
  end
  def start
    raise NotImplementedError.new 'Should have been implemented in order to declare a plugin'
  end
end

class A < Plugin
  def start
    puts "Hello, #{self.class}"
  end
end
пишет, что функция start не реализована? Он выполняет inherited перед созданием дочернего класса?

TDrive ★★★★★
() автор топика
Последнее исправление: TDrive (всего исправлений: 1)
Ответ на: комментарий от O02eg

Незачем, просто интересный момент.

TDrive ★★★★★
() автор топика
Ответ на: комментарий от TDrive

пишет, что функция start не реализована? Он выполняет inherited перед созданием дочернего класса?

При выполнении хука inherited дочерний класс (т.е. объект класса «Class») уже создан, но его тело (в том числе и объявление методов) ещё не выполнено, так что метод start класса A ещё не заменил метод родительского класса.

theNamelessOne ★★★★★
()

Просканируй свой каталог plugins на наличие необходимых классов и подгружай их в рантайме, в чем проблема-то?

f1xmAn ★★★★★
()
Ответ на: комментарий от f1xmAn

А лучше держи где-то список включенных плагинов и стартуй только их.

f1xmAn ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.