标签:method nodevalue 荣耀 exception 比赛 for util ESS 获取
王者荣耀游戏设计师根据英雄技能、属性、天赋等因素,将英雄划分为射手、辅助、打野、法师、坦克、战士等职业。一局比赛存在多类英雄可供选择。玩家在挑选游戏英雄时,合理的英雄职业搭配是赢得游戏胜利的基本保证。
工厂方法模式(Factory Method Pattern):工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
工厂方法模式涉及的设计原则有:
★依赖于抽象,不依赖于具体类
★对于扩展是开放的,对于修改是封闭的
★封装变化
★针对接口编程,不针对实现编程
工厂方法模式的通用类图:
工厂方法模式涉及的角色有:
● Product(抽象产品)
抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类或接口
● ConcreteProduct(具体产品)
具体产品实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,它们之间一一对应。
● Factory(抽象工厂)
在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,它与应用程序无关。任何在模式中创建对象的工厂类都必须实现该接口
● ConcreteFactory(具体工厂)
具体工厂是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,并可由客户调用,返回一个具体产品类的实例。在具体工厂类中包含了与应用程序紧密相关的逻辑,并且接受应用程序调用以创建产品对象。
创建工厂类HeroFactory(核心)
package com.practice.SimpleFactory;
public class HeroFactory {
static Hero hero = null;
public static Hero getHeroInstance(String heroTP) throws Exception {
if(heroTP.equalsIgnoreCase("Tank")) {
hero = new TankHero();
}else if(heroTP.equalsIgnoreCase("Wild")) {
hero = new WildHero();
}else if(heroTP.equalsIgnoreCase("Magus")) {
hero = new MagusHero();
}else if(heroTP.equalsIgnoreCase("Shoot")) {
hero = new ShootHero();
}else if(heroTP.equalsIgnoreCase("Auxiliary")) {
hero = new AuxiliaryHero();
}else {
throw new Exception();
}
return hero;
}
}
创建抽象接口类Hero
package com.practice.SimpleFactory;
public interface Hero {
void display();
}
创建具体产品类AuxiliaryHero(辅助英雄类)
package com.practice.SimpleFactory;
public class AuxiliaryHero implements Hero{
public void display() {
System.out.println("您的选择为:辅助(战地医生,为队友输血、解控、打鸡血)");
}
}
创建具体产品类MagusHero(法师英雄类)
package com.practice.SimpleFactory;
public class MagusHero implements Hero{
public void display() {
System.out.println("您的选择为:法师(法师,大杀器,基本就是战场上的核弹,一炸一大片,输出还十分高,最高效的人头收割器");
}
}
创建具体产品类ShootHero(射手英雄类)
package com.practice.SimpleFactory;
public class ShootHero implements Hero{
public void display() {
System.out.println("您的选择为:射手(射手,火力压制,利用大打击面形成火力网保护网中的近战英雄)");
}
}
创建具体产品类TankHero(坦克英雄类)
package com.practice.SimpleFactory;
public class TankHero implements Hero{
public void display() {
System.out.println("您的选择为:坦克(坦克主要是在前排吸收伤害,并且尽量控制敌人)");
}
}
创建具体产品类WildHero(打野英雄类)
package com.practice.SimpleFactory;
public class WildHero implements Hero{
public void display() {
System.out.println("您的选择为:打野(后排杀手,目标是在开战时以最快速度摧毁对方的输出主力)");
}
}
XML配置文件(Config.xml)
通过配置文件可以极大提高系统的扩展性,让软件实体更符合开闭原则。为了让系统更符合开闭原则和依赖倒置原则,需要做到"将抽象写在代码中,将具体写在配置里"通过修改无须编译的配置文件来提高系统的可扩展性和灵活性
<?xml version="1.0" encoding="UTF-8"?>
<config>
<className>Tank</className>
</config>
工具类读取XML文件信息(XMLUtilHero类)
在该工具类中,通过Java语言提供的DOM(Document Object Model,文档对象模型)API来实现对XML文档的操作,在DOM API中,XML文档以树形结构存储在内存中,可以通过相关的类对XML进行读取、修改等操作
package com.practice.Client;
import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class XMLUtilHero {
//该方法用于从XML配置文件中提取英雄名称,并返回该英雄名称
public static String getHeroName() {
try {
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src\\com\\practice\\Client\\config.xml"));
//获取包含英雄名称的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String dName = classNode.getNodeValue().trim();
return dName;
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
创建测试类Client类
package com.practice.Client;
import com.practice.Hero.Hero;
import com.practice.HeroFactory.HeroFactory;
public class Client {
public static void main(String [] args) {
Hero hero;
HeroFactory factory;
factory = (HeroFactory) XMLUtilHero.getHeroFactory();
hero = factory.produceHero();
hero.display();
}
}
代码运行结果:
从代码结构不难看出,当我们需要添加新英雄职业比如战士类英雄时,我们必须修改工厂类,加入要处理的逻辑,这违背了"开闭原则"。在简单工厂模式中,所有的产品都是由同一个工厂创建,工厂职责较重,业务逻辑比较复杂,具体产品与工厂类之间的耦合度较高,严重影响了系统的灵活性和扩展性,而工厂方法模式则可以很好地解决这一问题。
创建抽象产品类(Hero类)
package com.practice.Hero;
public interface Hero {
public void display();
}
创建具体产品类(AuxiliaryHero类(辅助英雄类))
package com.practice.Hero;
public class AuxiliaryHero implements Hero {
public void display() {
System.out.println("辅助:战地医生,为队友输血、解控、打鸡血");
}
}
创建具体产品类(MagusHero类(法师英雄类))
package com.practice.Hero;
public class MagusHero implements Hero {
public void display() {
System.out.println("法师:大杀器,基本就是战场上的核弹,一炸一大片,输出还十分高,最高效的人头收割器");
}
}
创建具体产品类(ShootHero类(射手英雄类))
package com.practice.Hero;
public class ShootHero implements Hero{
public void display() {
System.out.println("射手:火力压制,利用大打击面形成火力网保护网中的近战英雄");
}
}
创建抽象工厂类(HeroFactory)
package com.practice.HeroFactory;
import com.practice.Hero.Hero;
public interface HeroFactory {
Hero produceHero();
}
创建具体工厂类(AuxiliaryHeroFactory(辅助工厂类))
package com.practice.HeroFactory;
import com.practice.Hero.AuxiliaryHero;
import com.practice.Hero.Hero;
public class AuxiliaryHeroFactory implements HeroFactory {
public Hero produceHero() {
System.out.println("您的选择为:辅助");
return new AuxiliaryHero();
}
}
创建具体工厂类(MagusHeroFactory(法师工厂类))
package com.practice.HeroFactory;
import com.practice.Hero.Hero;
import com.practice.Hero.MagusHero;
public class MagusHeroFactory implements HeroFactory {
public Hero produceHero() {
System.out.println("您的选择为:法师");
return new MagusHero();
}
}
创建具体工厂类(ShootHeroFactory(射手工厂类))
package com.practice.HeroFactory;
import com.practice.Hero.Hero;
import com.practice.Hero.ShootHero;
public class ShootHeroFactory implements HeroFactory {
public Hero produceHero() {
System.out.println("您的选择为:射手");
return new ShootHero();
}
}
配置文件XML(config.xml)
<?xml version="1.0" encoding="UTF-8"?>
<config>
<HeroFactory>ShootHeroFactory</HeroFactory>
</config>
辅助类(XMLUtilHero读取XML文件)
package com.practice.Client;
import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class XMLUtilHero {
//该方法用于从XML配置文件中提取具体类类名。并返回一个实例对象
public static Object getHeroFactory() {
try {
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src\\com\\practice\\Client\\config.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("HeroFactory");
Node classNode = nl.item(0).getFirstChild();
String HeroFactory = classNode.getNodeValue();
//通过类名生成实例对象并将其返回
String ClassName = "com.practice.HeroFactory."+ HeroFactory;
Class<?> c = Class.forName(ClassName);
@SuppressWarnings("deprecation")
Object obj = c.newInstance();
return obj;
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
创建测试类(Client类)
package com.practice.Client;
import com.practice.Hero.Hero;
import com.practice.HeroFactory.HeroFactory;
public class Client {
public static void main(String [] args) {
Hero hero;
HeroFactory factory;
factory = (HeroFactory) XMLUtilHero.getHeroFactory();
hero = factory.produceHero();
hero.display();
}
}
运行结果
标签:method nodevalue 荣耀 exception 比赛 for util ESS 获取
原文地址:https://www.cnblogs.com/miaowulj/p/12146542.html