Ob'ekt turiga o'tish uchun Java alternativi

Java 8 da buyruqlar naqshini turli xil ob'ektlarning ob'ektlariga turli xil buyruqlarni topshirish uchun ishlatmoqchiman. Odamlar ob'ektlarning a'zolari bo'lsa, men jamoat tartibini buzuvchilarga ta'sir qilishni xohlamayman; Men bu a'zolarning buyruqlari yordamida faqat ni boshqarishni istayman. Muammo shundaki, bu a'zolarni (yoki yaxshiroq, paket-maxsus sozlashni) buyruqqa qanday ta'sir qilish kerak. Ularni interfeysning bir qismiga aylantirsam, ularni omma oldida ochaman. Ularni meros qoldirish variant emas, chunki men bir nechta merosga muhtojman. Xo'sh, komandalar sinfning bir qismi yoki interfeysning bir qismi sifatida ko'rinmasa, sozlovchilarni qanday qilib bilish mumkin?

Men shuni nazarda tutgan eng maqbul echim buyruqlar turini ishga tushirish va sinf ichidagi butunlay buyrug'ini bajarish uchun tegishli kurslarni olishdir (a'zolar shaxsiy bo'lishi mumkin - hatto yaxshi) , faqat kerakli ma'lumotlarni buyruqlar sinfidan chiqarib yuboradi. Ammo OO tilida ob'ekt turini ochish fikri meni mensimaslikka olib keladi. Yaxshi yo'l bormi?

2
Minimal, Complete va Verifiable misol ni taqdim qilsangiz sizga yordam beradigan lot oson bo'ladi > Muammoni faqat tushuntirib berish o'rniga.
qo'shib qo'ydi muallif Jon Skeet, manba
Minimal, Complete va Verifiable misol ni taqdim qilsangiz sizga yordam beradigan lot oson bo'ladi > Muammoni faqat tushuntirib berish o'rniga.
qo'shib qo'ydi muallif Jon Skeet, manba
Eng kam, to'liq va tekshirilishi mumkin bo'lgan namunadir, agar biror kishi ishlashga qodir bo'lmasa, u juda yaxshi. U hatto dizaynga ega bo'lmaganda ham amaliydir! Demak, quyida dasblinkenlight tufayli, men zarur bo'lgan namunani aniqlash uchun.
qo'shib qo'ydi muallif digitig, manba
Eng kam, to'liq va tekshirilishi mumkin bo'lgan namunadir, agar biror kishi ishlashga qodir bo'lmasa, u juda yaxshi. U hatto dizaynga ega bo'lmaganda ham amaliydir! Demak, quyida dasblinkenlight tufayli, men zarur bo'lgan namunani aniqlash uchun.
qo'shib qo'ydi muallif digitig, manba
Eng kam, to'liq va tekshirilishi mumkin bo'lgan namunadir, agar biror kishi ishlashga qodir bo'lmasa, u juda yaxshi. U hatto dizaynga ega bo'lmaganda ham amaliydir! Demak, quyida dasblinkenlight tufayli, men zarur bo'lgan namunani aniqlash uchun.
qo'shib qo'ydi muallif digitig, manba

9 javoblar

Visitor Pattern dan foydalaning:

  • Sizning yapılandırılabilir sinf Visitor ,
  • Sizning buyruqlaringiz klassi Element ,
  • dir
  • Siz konfiguratsiya qilingan sinfni buyruqning accept usuliga o'tkazasiz va buyruq buyruqlar turiga mos keladigan usulni chaqiradi.

Mana bir misol:

interface CommandVisitor {
    void visit(SetCommand1 cmd);
    void visit(SetCommand2 cmd);
}
interface Command {
    void accept(CommandVisitor v);
}
class SetCommand1 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}
class SetCommand2 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}

Endi sizning konfiguratsiya qilinadigan sinfingiz sizlarga yuborilgan buyruqlar turiga asosan "qo`ng'iroqlar" ni qabul qiladigan tashrif ortiqcha yuklarni SetCommand1 va SetCommand2 .

2
qo'shib qo'ydi
Ushbu yechim, paketli-maxsus API-ga kirish uchun, "turli-tuman bo'lgan sinflar" ni talab qiladi. Lekin menimcha, bu sizning ifoda muammolarini hal qilish yo'lingiz bilan keladi. Yangi buyruqlar va variantlarga yangi ma'lumotlar turlariga o'zgarmas.
qo'shib qo'ydi muallif mike, manba

Visitor Pattern dan foydalaning:

  • Sizning yapılandırılabilir sinf Visitor ,
  • Sizning buyruqlaringiz klassi Element ,
  • dir
  • Siz konfiguratsiya qilingan sinfni buyruqning accept usuliga o'tkazasiz va buyruq buyruqlar turiga mos keladigan usulni chaqiradi.

Mana bir misol:

interface CommandVisitor {
    void visit(SetCommand1 cmd);
    void visit(SetCommand2 cmd);
}
interface Command {
    void accept(CommandVisitor v);
}
class SetCommand1 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}
class SetCommand2 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}

Endi sizning konfiguratsiya qilinadigan sinfingiz sizlarga yuborilgan buyruqlar turiga asosan "qo`ng'iroqlar" ni qabul qiladigan tashrif ortiqcha yuklarni SetCommand1 va SetCommand2 .

2
qo'shib qo'ydi
Ushbu yechim, paketli-maxsus API-ga kirish uchun, "turli-tuman bo'lgan sinflar" ni talab qiladi. Lekin menimcha, bu sizning ifoda muammolarini hal qilish yo'lingiz bilan keladi. Yangi buyruqlar va variantlarga yangi ma'lumotlar turlariga o'zgarmas.
qo'shib qo'ydi muallif mike, manba

Visitor Pattern dan foydalaning:

  • Sizning yapılandırılabilir sinf Visitor ,
  • Sizning buyruqlaringiz klassi Element ,
  • dir
  • Siz konfiguratsiya qilingan sinfni buyruqning accept usuliga o'tkazasiz va buyruq buyruqlar turiga mos keladigan usulni chaqiradi.

Mana bir misol:

interface CommandVisitor {
    void visit(SetCommand1 cmd);
    void visit(SetCommand2 cmd);
}
interface Command {
    void accept(CommandVisitor v);
}
class SetCommand1 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}
class SetCommand2 : Command {
    public void accept(CommandVisitor v) {v.visit(this);}
}

Endi sizning konfiguratsiya qilinadigan sinfingiz sizlarga yuborilgan buyruqlar turiga asosan "qo`ng'iroqlar" ni qabul qiladigan tashrif ortiqcha yuklarni SetCommand1 va SetCommand2 .

2
qo'shib qo'ydi
Ushbu yechim, paketli-maxsus API-ga kirish uchun, "turli-tuman bo'lgan sinflar" ni talab qiladi. Lekin menimcha, bu sizning ifoda muammolarini hal qilish yo'lingiz bilan keladi. Yangi buyruqlar va variantlarga yangi ma'lumotlar turlariga o'zgarmas.
qo'shib qo'ydi muallif mike, manba

Ichki mashg'ulotlar sinflarni maxsus sinf a'zolariga kirishi mumkin, shuning uchun siz buyruqni ichki qismga aylantira olasiz:

interface Command {
    void execute();
}

class Model {
    private int fieldA;
    private String fieldB;

    ...

    public Command getCommand() {
        return new MyCommand();
    }

    ...

    private class MyCommand implements Command {
        @Override
        public void execute() {
            fieldA = 10;
            fieldB = "Foo";
            //Or use setter...
        }
    }
}

Keyin:

Model model = ...;
Command command = model.getCommand();
//usage...

Shu tarzda MyCommand Model maydoniga kirishi mumkin, ammo hech narsa boshqa.

1
qo'shib qo'ydi

Ichki mashg'ulotlar sinflarni maxsus sinf a'zolariga kirishi mumkin, shuning uchun siz buyruqni ichki qismga aylantira olasiz:

interface Command {
    void execute();
}

class Model {
    private int fieldA;
    private String fieldB;

    ...

    public Command getCommand() {
        return new MyCommand();
    }

    ...

    private class MyCommand implements Command {
        @Override
        public void execute() {
            fieldA = 10;
            fieldB = "Foo";
            //Or use setter...
        }
    }
}

Keyin:

Model model = ...;
Command command = model.getCommand();
//usage...

Shu tarzda MyCommand Model maydoniga kirishi mumkin, ammo hech narsa boshqa.

1
qo'shib qo'ydi

Ichki mashg'ulotlar sinflarni maxsus sinf a'zolariga kirishi mumkin, shuning uchun siz buyruqni ichki qismga aylantira olasiz:

interface Command {
    void execute();
}

class Model {
    private int fieldA;
    private String fieldB;

    ...

    public Command getCommand() {
        return new MyCommand();
    }

    ...

    private class MyCommand implements Command {
        @Override
        public void execute() {
            fieldA = 10;
            fieldB = "Foo";
            //Or use setter...
        }
    }
}

Keyin:

Model model = ...;
Command command = model.getCommand();
//usage...

Shu tarzda MyCommand Model maydoniga kirishi mumkin, ammo hech narsa boshqa.

1
qo'shib qo'ydi

Ushbu echimdagi buyumlarni buyruqlarni o'zlari taqdim etishga majbur qilasiz. Bu ob'ektlar internatini yashirish imkonini beradi. Buyruqlar barcha Command dan olinadi.

@FunctionalInterface
public interface Command { public void execute(); }

Masalan, CommandA .

public interface CommandA extends Command { }

Ushbu ramka bilan ishlaydigan ob'ektlar Commandable ni amalga oshirishi kerak. Ushbu interfeysning har bir quvvatlangan buyrug'i uchun bir usuli bor va ob'ektlar berilgan buyruqning o'ziga xos bajarilishini qaytarishga imkon beradi.

public interface Commandable { public CommandA getCommandA(); }

Quyidagi tarzda foydalaning.

public class Type implements Commandable {

    private boolean isRunning = false;

    public CommandA getCommandA() {
        return() -> {isRunning = true;};
    }

    public boolean isRunning() {
        return isRunning;
    }

    public static void main(String[] args) {
        Type type = new Type();
        System.out.println(type.isRunning());

        Commandable object = type;
        CommandA command = object.getCommandA();
        command.execute();

        System.out.println(type.isRunning());
    }

}

Chiqish - bu

false
true

Shu bilan bir qatorda, moslamalarni Commandable ni qo'llashni istamasangiz, buyruq registratsiyasi turlarini yaratishingiz mumkin va u erda mavjud bo'lgan buyruqlarni amalga oshirishni ro'yxatga olish uchun har bir obyektni majburlashingiz mumkin.

0
qo'shib qo'ydi

Ushbu echimdagi buyumlarni buyruqlarni o'zlari taqdim etishga majbur qilasiz. Bu ob'ektlar internatini yashirish imkonini beradi. Buyruqlar barcha Command dan olinadi.

@FunctionalInterface
public interface Command { public void execute(); }

Masalan, CommandA .

public interface CommandA extends Command { }

Ushbu ramka bilan ishlaydigan ob'ektlar Commandable ni amalga oshirishi kerak. Ushbu interfeysning har bir quvvatlangan buyrug'i uchun bir usuli bor va ob'ektlar berilgan buyruqning o'ziga xos bajarilishini qaytarishga imkon beradi.

public interface Commandable { public CommandA getCommandA(); }

Quyidagi tarzda foydalaning.

public class Type implements Commandable {

    private boolean isRunning = false;

    public CommandA getCommandA() {
        return() -> {isRunning = true;};
    }

    public boolean isRunning() {
        return isRunning;
    }

    public static void main(String[] args) {
        Type type = new Type();
        System.out.println(type.isRunning());

        Commandable object = type;
        CommandA command = object.getCommandA();
        command.execute();

        System.out.println(type.isRunning());
    }

}

Chiqish - bu

false
true

Shu bilan bir qatorda, moslamalarni Commandable ni qo'llashni istamasangiz, buyruq registratsiyasi turlarini yaratishingiz mumkin va u erda mavjud bo'lgan buyruqlarni amalga oshirishni ro'yxatga olish uchun har bir obyektni majburlashingiz mumkin.

0
qo'shib qo'ydi

Ushbu echimdagi buyumlarni buyruqlarni o'zlari taqdim etishga majbur qilasiz. Bu ob'ektlar internatini yashirish imkonini beradi. Buyruqlar barcha Command dan olinadi.

@FunctionalInterface
public interface Command { public void execute(); }

Masalan, CommandA .

public interface CommandA extends Command { }

Ushbu ramka bilan ishlaydigan ob'ektlar Commandable ni amalga oshirishi kerak. Ushbu interfeysning har bir quvvatlangan buyrug'i uchun bir usuli bor va ob'ektlar berilgan buyruqning o'ziga xos bajarilishini qaytarishga imkon beradi.

public interface Commandable { public CommandA getCommandA(); }

Quyidagi tarzda foydalaning.

public class Type implements Commandable {

    private boolean isRunning = false;

    public CommandA getCommandA() {
        return() -> {isRunning = true;};
    }

    public boolean isRunning() {
        return isRunning;
    }

    public static void main(String[] args) {
        Type type = new Type();
        System.out.println(type.isRunning());

        Commandable object = type;
        CommandA command = object.getCommandA();
        command.execute();

        System.out.println(type.isRunning());
    }

}

Chiqish - bu

false
true

Shu bilan bir qatorda, moslamalarni Commandable ni qo'llashni istamasangiz, buyruq registratsiyasi turlarini yaratishingiz mumkin va u erda mavjud bo'lgan buyruqlarni amalga oshirishni ro'yxatga olish uchun har bir obyektni majburlashingiz mumkin.

0
qo'shib qo'ydi