Sizning biringizni egallagan uchinchi tomon sinfining namunasini olish

Xullas, vaziyat shunday: Men ko'p o'yindagi o'yinni yaratyapman, va men do'stlarimni istayman ..., buning uchun botlarni yaratish imkoniyatiga ega bo'lishni istayman. Shunday qilib men nima qilmoqchiman, mavhumlik botsheva {} yaratish va botslarga funksiyalarni belgilash, keyin ularni amalga oshirish kerak bo'ladi: hali juda to'g'ri oldinga.

Men qayerda qoldim, ularni keyinchalik qanday qo'shishim kerak? Bot ning barcha merosxo'rlarini topish uchun ko'zgu yoki shunga o'xshash biror narsani ishlatasizmi? Yoki .jar fayllarini qidirish kerakmi?

Hozirgi kunga qadar men buni qanday qildim (soddalashtirilgan, sinflar bir xil faylda yo'q va boshqalar):

abstract class Bot{
  public int play();
  //...
}

class Bot1 extends Bot{
  @override
  public int play(){/*do stuff*/}
  //...
}

va keyin har bir botdan biri bo'lish kerak bo'lsa:

ArrayList bots = new ArrayList<>();
bots.add(new Bot1());
//...

Men bu muammolardan foydalanishni istasam, bu kodni Bot1 deb atash qiyin kodli bo'lgani uchun men o'z kodlarini tahrirlash uchun o'zlarining shaxsiy botlarini qo'shishga ruxsat berishim kerak.

Mening savolim quyidagilardan iboratki, buni qattiq kodlashsiz amalga oshirish mumkinmi? Men buni bilaman, Chtoby ostavit bu (mods va shunga o'xshash) ishlarni bajaradi, ammo buni qanday qilish kerakligi haqida hech qanday maslahatim yo'q. Hozirgacha mening tadqiqotlarim hech qanday natija bermadi (ehtimol, men uni oddiy jumla bilan qanday tushuntirish kerakligini bilmaganim uchun ...), shuning uchun maslahatning har qanday maslahatlaridan foydalanishingiz mumkin .

Bundan tashqari, men OOP va shunga o'xshashlarni yaxshi tushunaman, lekin men o'zimni aks ettiradigan va getClass() narsalar uchun yangi ...

3
Bu yerda fikrlar ko'p: stackoverflow.com/questions/492184/…
qo'shib qo'ydi muallif dnault, manba
qo'shib qo'ydi muallif dnault, manba
Standart Ustasi naqshini ko'rib chiqing. Keyin sinflarni o'rnatish uchun reflection dan foydalanishingiz mumkin.
qo'shib qo'ydi muallif ahoxha, manba

6 javoblar

Buni amalga oshirishning eng oddiy yo'li (tashqi ramkalarsiz), ehtimol interfeys sifatida Bot ni belgilash ( SPI , xizmat ko'rsatuvchi provayder interfeysi) ni kiritib, so'ngra o'rnatilgan Service Loader mexanizmi. So'ngra maxsus Bot ilovalari sizning ilovangizning sinfi yo'lidan ochilishi uchun (JARlar sifatida) tarqatilishi kerak.

Shunday qilib, bir narsa:

SPI shartnomasi:

public interface Bot {
    int play();
}

Ilova (bu kodni META-INF papkasida, jumladan, bog'langan hujjatlarda ko'rsatilgan katalog strukturasiga ega bo'lgan JARga paketlash kerak):

public class MyBot implements Bot {
    @Override
    public int play() {
       //do something
    }
}

Qidirmoq:

import java.util.ServiceLoader;

public class BotResolver {

    private final ServiceLoader loader;

    public BotResolver() {
        loader = ServiceLoader.load(Bot.class);
    }

    /**
     * Gets all bot implementations that are currently available in the classpath.
     */
    public List getAllBots() {

        List allBots = new ArrayList<>();
        Iterator it = loader.iterator();

        while (it.hasNext()) {
           allBots.add(it.next());
        }

        return allBots;
    }
}
4
qo'shib qo'ydi

Bu sizning so'ragan narsangiz bo'lmasa-da, lekin ma'lum bir sinfning barcha quyi sinflarini ishlash vaqtida ishlashga harakat qilsangiz yaxshi fikr emas. Nega do'stlaringizni o'zingizning Bot misollarini bitta qo'shiq orqali so'rashga taklif qilasiz?

public enum BotHolder {
    BOTS;

    private final List bots = new ArrayList<>();

    public void registerBot(Bot bot) {
        bots.add(bot);
    }

    public List get() {
        return bots;
    }
}
2
qo'shib qo'ydi

Mick tomonidan yaxshi javob.

Mana mening halim ( ServiceLoader API dan foydalanmasdan, lekin shunga o'xshash yondashuv).

  1. Mulk faylini BotClasses = nomi bilan ta'riflab bering do'stingizning bot sinfining to'liq malakali yo'li. (bir nechta uchun sinflar ularni ; ) kabi ba'zi cheklovchilar bilan ajratadi.

  2. BotClasses xususiyati qiymatini chegarachilar bilan ajratib, keyin har bir to'liq malakali sinf nomi uchun foydalaning:

Asosiy newObj = (Bot)   Class.forName (strFullyQualifiedClassName) .newInstance ();

Bu faqat Bot ilovalarida standart/nor-arg tuzuvchi bo'lsa ishlaydi.

1
qo'shib qo'ydi

Siz do'stlaringizni bot interfeysingizni amalga oshiradigan o'z bot sinflarini yaratishingiz mumkin, so'ngra ularni papkaga joylashtiring va classLoader.loadclass dan foydalanib har bir klassni yuklang. Har bir sinf talab qilinadigan interfeysi amalga oshiradimi yoki yo'qligini tekshirish uchun instanceof dan foydalaning. Men buni haftaning oldingi kunlarida sinash uchun oddiy plagin tizimini yozgan edim, lekin kodni hozircha kirita olmadim, ammo bu elementlardan qanday foydalanishi haqida ma'lumot omadga ega!

1
qo'shib qo'ydi

mavzusida o'qiganimdan Java-da ma'lum bir sinfning barcha quyi sinflarini qanday topasiz? , bu har bir sinfda "qo'pol kuch" dan boshqa yo'lni qilishning haqiqiy usuli bo'lmasa-da, bu Botning pastki klassi .

Savolingizga javob berish uchun, yuqoridagi mavzuda aytib o'tish mumkin.

1
qo'shib qo'ydi

If you are using Spring, you can request that the Bot implementations are annotated with @Component so that your application can use a component scan and then use @Autowired private List bots; to access them.

0
qo'shib qo'ydi
Men NetBeansni bir oydan kamroq vaqtdan beri foydalanmoqdaman, shuning uchun (bahor @ izohlar deb hisoblasa), men bunga hali yangi emasman. Maslahat uchun rahmat, men buni yaqinda tekshirib ko'raman.
qo'shib qo'ydi muallif CLOVIS, manba