本文主要讲的是简单工厂模式与抽象工厂模式的区别。
一、简单工厂模式
简单工厂模式的优点:我们可以对创建的对象进行一些 “加工” ,而且客户端并不知道,因为工厂隐藏了这些细节。 如果,没有工厂的话,那我们是不是就得自己在客户端上写这些代码,这就好比本来可以在工厂里生产的东西,拿来自己手工制作,不仅麻烦以后还不好维护。
操作说明:定义一个接口,然后定义一个工厂,最后写出所有需要生产的产品实例并继承接口。
接口:
//定义的接口,具有运算功能的接口
public interface IOperation {
public double getResult(double numberA,double numberB) throws Exception;
工厂:
//创建一个四则运算的工厂,根据客户端的要求,创建对应的运算对象
public class SimpleFactory {
Operation createOperation(String name){
Operation operation = null;
switch (name){
case "+":
operation = new Add();
break;
case "-":
operation = new Sub();
break;
case "*":
operation = new Mul();
break;
case "/":
operation = new Div();
break;
}
return operation;
}
}
具体运算实例:
加法运算:
public class Add implements Operation{
// 加法计算
public double getResult(double numberA, double numberB) {
return numberA + numberB;
}
另外三种(减法、除法、乘法)就不写上来了,同上。
客服端:
import java.util.Scanner;
public class Client {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
IOperation iOperation = null;
SimpleFactory simpleFactory = new SimpleFactory();
System.out.println("请输入运算符:");
String name = input.next();
iOperation=simpleFactory.createOperation(name);
System.out.println("请输入要操作的数:");
double x = input.nextInt();
double y = input.nextInt();
try {
System.out.println(iOperation.getResult(x, y));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
结果如下:
结论:从上面可以看出 如果需要在方法里写很多与对象创建有关的业务代码, 而且需要的创建的对象还不少的话,我们要在这个简单工厂类里编写很多个方法, 每个方法里都得写很多相应的业务代码, 而每次增加子类或者删除子类对象的创建都需要打开这简单工厂类来进行修改。这会导致这个简单工厂类很庞大臃肿、耦合性高,而且增加、删除某个子类对象的创建都需要打开简单工厂类来进行修改代码也违反了开-闭原则。
二、抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
简介:抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
优点:最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同产品配置,可扩展性强。
下面就拿一个例子具体看看:
例子:建造一个英雄,怪兽工厂。
抽象英雄和怪兽:
public abstract class Hero implements ISkill{
private int roleATK;//攻击力
private int roleDEF; //防御力
private int roleHP; //体力
private String roleName; //名称
}//英雄抽象类结束
public abstract class Monster implements ISkill{
private int roleATK;//攻击力
private int roleDEF; //防御力
private int roleHP; //体力
private String roleName; //名称
//...get,set省略
}//怪兽抽象类结束
怪物和英雄技能接口:
public interface ISkill {
public void skill();
}
建造抽象角色建造工厂:
//总工厂,作用创建返回具体实例工厂
public abstract class AbstractRoleFactory {
public static AbstractRoleFactory abstractRoleFactory = null;
public static AbstractRoleFactory factory(int type){
switch (type) {
case 1:
abstractRoleFactory = new HeroFactory();
break;
case 2:
abstractRoleFactory = new MonsterFactory();
default:
break;
}
return abstractRoleFactory;
}
public abstract ISkill createRole(int type);
}
具体英雄工厂:
public class HeroFactory extends AbstractRoleFactory{
private Hero hero;
@Override
public ISkill createRole(int type) {
switch (type) {
case 1:
hero = new WarriorEntity();//战士
break;
case 2:
hero = new MasterEntity();//法师
break;
case 3:
hero = new ArcherEntity();//弓箭手
break;
}
return hero;//根据需求返回具体的一种英雄
}
}
具体怪物工厂:
public class MonsterFactory extends AbstractRoleFactory{
private Monster monster;
@Override
public ISkill createRole(int type) {
switch (type) {
case 1:
monster = new GeneralMonster();//普通怪物
break;
case 2:
monster = new EliteMonster(); //精英怪物
break;
case 3:
monster = new BOSSMonster(); //boss怪物
break;
}
return monster;//返回具体的一个怪物
}
}
具体的战士等等产品类就省略了,想生产啥样的就写啥样的东西。
具体产品类
工厂要造的产品也就是:战士、法师、弓箭手、普通怪物、精英怪物、boss怪物。当要添加一个角色的时候,只需要添加一个该角色的具体类,然后加到工厂去即可。无需改变原有代码。
客户端:
造英雄:
造怪物:
好了演示到此结束。
总结:工厂模式简单来说就是,你不再需要去自己new一个对象了,具体产品怎么产生已经在工厂面包装好了。你只需要提供产品的相关信息,就可以拿到你想要的对象了。目前也只局限于会用写出来代码。
附上参考的文章地址:讲的很清楚仔细:
https://blog.csdn.net/kocscs123/article/details/53243847
https://blog.csdn.net/u012156116/article/details/80857255?tdsourcetag=s_pcqq_aiomsg