王者荣耀这款游戏目前一共有100位英雄,游戏设计师根据英雄技能、属性、天赋等因素,将英雄划分为射手、辅助、打野、法师、坦克、战士等职业。
在本实例中,声明了坦克、法师、射手、刺客、战士、辅助等多个工厂子类,每个工厂生产相应职业的英雄。
工厂方法模式的理解:
高度概括:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
当系统准备为用户提供某个类的子类的实例,又不想让用户代码和该子类形成耦合时,就可以使用工厂方法模式来设计系统,工厂方法模式的关键是在一个接口或抽象类中定义一个抽象方法,该方法返回某一个类的子类的实例,该抽象类或接口让其子类或实现该接口的类通过重写这个抽象方法返回某个子类的实例。
工厂方法模式结构中的四种角色:
①抽象产品(Product):抽象类或接口负责定义具体产品必须实现的方法;
②具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品是Product的子类,如果Product是一个接口,那么具体产品是实现Product接口的类;
③构造者(Creator):一个接口或抽象类。构造者负责定义一个称作工厂方法的抽象方法,该方法返回具体产品类的实例;
④具体构造者(ConcreteCreator):如果构造者是抽象类,具体构造者是构造者的子类,如果构造者是接口,具体构造者是实现构造者的类。具体构造者重写工厂方法使该方法返回具体产品的实例。
工厂方法模式的UML类图:
工厂方法模式的优缺点:
优点:
①使用工厂方法可以让用户的代码和某个特定类的子类的代码解耦;
②工厂方法使用户不必知道他所使用的对象是怎样被创建的,只需知道该对象有哪些方法即可;
③满足“开—闭原则”。
缺点:
①在一定的程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销;
②由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
工厂方法模式的适用情景:
①用户需要一个类的子类的实例,但不希望该类的子类形成耦合;
②用户需要一个类的子类的实例,但用户不知道该类有哪些子类可用。
eclipse结构图
主函数【应用(Application)】
Application.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
import angle_factoryPattern.Master;
import angle_factoryPattern.MasterHeroSkin;
import angle_factoryPattern.Shooter;
import angle_factoryPattern.ShooterHeroSkin;
import angle_factoryPattern.Support;
import angle_factoryPattern.SupportHeroSkin;
import angle_factoryPattern.Tank;
import angle_factoryPattern.TankHeroSkin;
import angle_factoryPattern.Warrior;
import angle_factoryPattern.WarriorHeroSkin;
public class Application{
public static void main(String args[]){
HeroSkin skin=new MasterHeroSkin();
Hero hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
System.out.println("");
skin=new ShooterHeroSkin();
hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
System.out.println("");
skin=new SupportHeroSkin();
hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
System.out.println("");
skin=new TankHeroSkin();
hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
System.out.println("");
skin=new WarriorHeroSkin();
hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
System.out.println("");
skin=new AssassinHeroSkin();
hero=skin.getHero();
System.out.println(hero.getName()+"及其皮肤举例:");
System.out.println(hero.getConstitute());
}
}
抽象产品
Hero.java
package angle_factoryPattern;
public abstract class Hero{
String constitute;
String name;
public String getName(){
return name;
}
public String getConstitute(){
return constitute;
}
}
具体产品
Assassin.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Assassin extends Hero{
String part1=" 韩信皮肤:";
String part2=" 李白皮肤:";
String part3=" 赵云皮肤:";
String part4=" ......";
public Assassin(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
Master.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Master extends Hero{
String part1=" 诸葛亮皮肤:";
String part2=" 高渐离皮肤:";
String part3=" 安琪拉皮肤:";
String part4=" ......";
public Master(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
Shooter.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Shooter extends Hero{
String part1=" 虞姬皮肤:";
String part2=" 伽罗皮肤:";
String part3=" 后羿皮肤:";
String part4=" ......";
public Shooter(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
Support .java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Support extends Hero{
String part1=" 庄周皮肤:";
String part2=" 刘禅皮肤:";
String part3=" 孙膑皮肤:";
String part4=" ......";
public Support(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
Tank.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Tank extends Hero{
String part1=" 项羽皮肤:";
String part2=" 白起皮肤:";
String part3=" 梦奇皮肤:";
String part4=" ......";
public Tank(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
Warrior.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public class Warrior extends Hero{
String part1=" 花木兰皮肤:";
String part2=" 程咬金皮肤:";
String part3=" 老夫子皮肤:";
String part4=" ......";
public Warrior(String name,String [] a,String [] b,String [] c){
this.name=name;
for(int i=0;i<=a.length-1;i++){
part1=part1+a[i]+'、';
}
for(int j=0;j<=b.length-1;j++){
part2=part2+b[j]+'、';
}
for(int k=0;k<=c.length-1;k++){
part3=part3+c[k]+'、';
}
constitute=part1+'\n'+part2+'\n'+part3+'\n'+part4;
}
}
构造者
HeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Hero;
public interface HeroSkin{
public abstract Hero getHero(); //工厂方法
}
具体构造者
AssassinHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Master;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class AssassinHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"教廷特使","飞衡","街头霸王","白龙吟","逐梦之影"};
String [] b={"范海辛","千年之狐","敏锐之力","凤求凰"};
String [] c={"未来纪元","皇家上将","忍·炎影","嘻哈天王","白执事","引擎之心"};
Hero hero=new Assassin("刺客类英雄",a,b,c);
return hero;
}
}
MasterHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Master;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class MasterHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"黄金分割率","星航指挥官","武陵仙君","掌控之力"};
String [] b={"金属狂潮","死亡摇滚","玩趣恶龙"};
String [] c={"玩偶对对碰","魔法小厨娘","心灵骇客","如懿"};
Hero hero=new Master("法师类英雄",a,b,c);
return hero;
}
}
ShooterHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Shooter;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class ShooterHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"加勒比小姐","霸王别姬","凯尔特女王","云霓雀翎"};
String [] b={"花见巫女","箭雨风息","太华"};
String [] c={"精灵王","阿尔法小队","辉光之辰","黄金射手座","如梦令"};
Hero hero=new Shooter("射手类英雄",a,b,c);
return hero;
}
}
SupportHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Support;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class SupportHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"鲤鱼之梦","蜃楼王","云端筑梦师","奇妙博物学","玄嵩"};
String [] b={"英喵野望","绅士熊猫","天才门将"};
String [] c={"未来旅行","天使之翼","妖精王","归墟梦演"};
Hero hero=new Supporter("辅助类英雄",a,b,c);
return hero;
}
}
TankHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Tank;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class TankHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"帝国元帅","海滩派对","苍穹之光","职棒王牌","霸王别姬","科学大爆炸"};
String [] b={"白色死神","无畏之灵·狰","昼夜王子"};
String [] c={"美梦成真","胖达荣荣"};
Hero hero=new Tank("坦克类英雄",a,b,c);
return hero;
}
}
WarriorHeroSkin.java
package angle_factoryPattern;
import angle_factoryPattern.Warrior;
import angle_factoryPattern.Hero;
import angle_factoryPattern.HeroSkin;
public class WarriorHeroSkin implements HeroSkin{
public Hero getHero(){
String [] a={"剑舞者","兔女郎","水晶猎龙者","青春决赛季","冠军飞将","麒麟志"};
String [] b={"华尔街大亨","爱与正义","星际陆战队","功夫厨神","活力突击"};
String [] c={"功夫老勺","潮流仙人","圣诞老人"};
Hero hero=new Warrior("战士类英雄",a,b,c);
return hero;
}
}
运行结果截图
更多设计模式在王者荣耀中的应用请点击我的→设计模式在王者荣耀中的应用专栏
感谢阅读