Dalam pembangunan harian, kita sering menghadapi situasi di mana terdapat banyak algoritma atau strategi untuk melaksanakan fungsi Kita boleh melaksanakan fungsi ini berdasarkan algoritma atau strategi yang berbeza. Contohnya: Jika anda ingin mengira kaedah pengiraan logistik, semuanya dibilkan. Penghantaran ekspres yang berbeza mempunyai kaedah pengebilan yang berbeza, seperti JD Express, Best Express dan YTO Express. Cara pengiraan kos penghantaran adalah berbeza antara mereka. Jadi bagaimana kita mencapainya? Yang mudah ialah jika...lain...atau tukar...kes.... Kedua-dua pelaksanaan ini dipanggil pengekodan keras. Jika terdapat kaedah pengebilan baharu seperti Yunda Express, maka kami perlu mengubah suai kod sumber algoritma kami. Ini akan menjadikan kod menjadi kembung dan sukar untuk dikekalkan.
Jadi, apa yang perlu kita capai ialah masing-masing mempunyai algoritma sendiri, dan kita hanya perlu memilih kaedah yang mana untuk memanggil pelanggan.
Kelas persekitaran (Konteks): Dikonfigurasikan dengan objek ConcreteStrategy. Kekalkan rujukan kepada objek Strategi. Anda boleh menentukan antara muka untuk membenarkan Strategi mengakses datanya.
Kelas strategi abstrak (Strategi): mentakrifkan antara muka awam semua algoritma yang disokong. Konteks menggunakan antara muka ini untuk memanggil algoritma yang ditakrifkan oleh ConcreteStrategy.
Kelas Strategi Konkrit (ConcreteStrategy): melaksanakan algoritma khusus dengan antara muka Strategi.
Ambil kadar tambang syarikat ekspres yang berbeza sebagai contoh:
Langkah 1: Tentukan kelas strategi abstrak (kaedah pengebilan)
public interface CommandStrategy { /** * 计费方式 * @param message */ void calMoney(String message); }
Langkah 2: Tentukan kelas strategi khusus (kelas algoritma yang berbeza melaksanakan antara muka ini)
public class BaiShiCommand implements CommandStrategy { /** * 百世快递计费方式 * @param message */ @Override public void calMoney(String message) { System.out.println("百世快递收费方式:"+"起步20,每公斤6元"); } }
public class JingDongCommand implements CommandStrategy { /** * 京东快递计费方式 * @param message */ @Override public void calMoney(String message) { System.out.println("京东快递收费方式:"+"起步30,每公斤5元"); } }
public class YuanTongCommand implements CommandStrategy { /** * 圆通快递计费方式 * @param message */ @Override public void calMoney(String message) { System.out.println("圆通快递收费方式:"+"起步10,每公斤8元"); } }
Langkah 3: Tentukan kelas persekitaran
public class CommandContext { public CommandStrategy getInstance(String commandType) { CommandStrategy commandStrategy = null; Map<String, String> allClazz = CommandEnum.getAllClazz(); //拿到对应算法类对应的路径 String clazz = allClazz.get(commandType.trim().toLowerCase()); if (StringUtils.isNotEmpty(clazz)) { try { try { //创建一个对象实例 commandStrategy = (CommandStrategy) Class.forName(clazz).newInstance();//调用无参构造器创建实例 } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } System.out.println("commandStrategy:"+commandStrategy); return commandStrategy; } }
Tentukan penghitungan Contoh:
public enum CommandEnum { JingDong("京东", "com.liubujun.design.command.JingDongCommand"), BaiShi("百世", "com.liubujun.design.command.BaishiCommand"), YuanTong("圆通", "com.liubujun.design.command.YuanTongCommand"); private String name; private String clazz; public static Map<String, String> getAllClazz() { Map<String, String> map = new HashMap<>(8); System.out.println("==================="+Arrays.toString(CommandEnum.values())+"================"); for (CommandEnum commandEnum : CommandEnum.values()) { map.put(commandEnum.getCommand(), commandEnum.getClazz()); } return map; } public String getCommand() { return name; } CommandEnum(String command, String clazz) { this.name = command; this.clazz = clazz; } public void setCommand(String command) { this.name = command; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } }
Pelanggan:
public class MainStart { public static void main(String[] args) { String message = "京东"; CommandContext commandContext = new CommandContext(); //拿到message对应算法的对象实例 CommandStrategy commandStrategy = commandContext.getInstance(message); commandStrategy.calMoney(message); } }
Dengan cara ini, pelanggan boleh terus menghubungi kaedah pengebilan penghantaran ekspres mana
Kebaikan:
1) Siri algoritma berkaitan Hierarki kelas Strategi mentakrifkan satu siri algoritma atau gelagat boleh guna semula untuk Konteks. Warisan membantu mengekstrak fungsi biasa dalam algoritma ini.
2) Menyediakan cara untuk menggantikan perhubungan warisan: Warisan menyediakan cara lain untuk menyokong berbilang algoritma atau gelagat. Anda boleh mensubkelaskan kelas Konteks secara langsung untuk memberikan kelakuan yang berbeza. Tetapi ini akan mengekodkan tingkah laku keras ke dalam Konteks dan mencampurkan pelaksanaan algoritma dengan pelaksanaan Konteks, menjadikan Konteks sukar untuk difahami, dikekalkan dan dilanjutkan, dan ia tidak boleh mengubah algoritma secara dinamik. Anda akan mendapat sekumpulan kelas yang berkaitan, satu-satunya perbezaan di antara mereka ialah algoritma atau tingkah laku yang mereka gunakan. Merangkum algoritma dalam kelas Strategi bebas membolehkan anda mengubahnya secara bebas daripada Konteksnya, menjadikannya mudah untuk ditukar, mudah difahami dan mudah dilanjutkan.
3) Hapuskan beberapa pernyataan bersyarat if else: Mod strategi menyediakan alternatif kepada menggunakan pernyataan bersyarat untuk memilih gelagat yang diingini. Apabila tingkah laku yang berbeza disusun dalam kelas, sukar untuk mengelak daripada menggunakan pernyataan bersyarat untuk memilih tingkah laku yang sesuai. Tingkah laku enkapsulasi dalam kelas Strategi yang berasingan menghapuskan pernyataan bersyarat ini. Kod dengan banyak pernyataan bersyarat biasanya menunjukkan keperluan untuk menggunakan mod Strategi.
4) Pilihan mod Strategi pelaksanaan boleh menyediakan pelaksanaan berbeza bagi gelagat yang sama. Pelanggan boleh memilih daripada strategi yang berbeza berdasarkan keperluan pertukaran masa/ruang yang berbeza.
Kelemahan:
1) Pelanggan mesti mengetahui semua kelas dasar dan memutuskan yang mana satu untuk digunakan: Model ini mempunyai potensi kelemahan, iaitu pelanggan mesti memilih Strategi yang sesuai mesti tahu perbezaan antara Strategi ini. Pada ketika ini, isu pelaksanaan tertentu mungkin perlu didedahkan kepada pelanggan. Oleh itu, mod Strategi hanya diperlukan apabila varian gelagat berbeza ini berkaitan dengan gelagat pelanggan.
2) Overhed komunikasi antara Strategi dan Konteks: Tidak kira sama ada algoritma yang dilaksanakan oleh setiap ConcreteStrategy adalah mudah atau kompleks, semuanya berkongsi antara muka yang ditakrifkan oleh Strategi. Oleh itu, ada kemungkinan bahawa beberapa ConcreteStrategy tidak akan menggunakan semua maklumat yang dihantar kepada mereka melalui antara muka ini; ConcreteStrategy yang mudah mungkin tidak menggunakan sebarang maklumat! Ini bermakna kadangkala Konteks akan mencipta dan memulakan parameter yang tidak akan digunakan. Jika masalah sedemikian wujud, gandingan yang lebih ketat antara Strategi dan Konteks akan diperlukan.
3) Corak strategi akan menghasilkan penjanaan banyak kelas strategi: bilangan objek boleh dikurangkan ke tahap tertentu dengan menggunakan corak flyweight. Peningkatan Bilangan Objek Strategi meningkatkan bilangan objek dalam aplikasi. Kadangkala anda boleh mengurangkan overhed ini dengan melaksanakan Strategi sebagai objek tanpa kewarganegaraan yang boleh dikongsi oleh pelbagai Konteks. Sebarang keadaan yang tinggal dikekalkan oleh Konteks. Konteks memberikan keadaan ini pada setiap permintaan kepada objek Strategi. Strategi yang dikongsi tidak seharusnya mengekalkan keadaan antara panggilan.
Atas ialah kandungan terperinci Pelaksanaan Corak Strategi dalam Corak Reka Bentuk Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!