工厂模式可以细分为三种模式,分别为:简单工厂模式,工厂方法,抽象工厂。下面是对这三种模式自己的学习见解,希望大家共同来交流呀。
1,简单工厂模式:工厂类是根据提供给它的参数,返回的是几个可能产品中的一个类的实例;下图为它的结构图:
以设计一个计算器为例:
//运算类
class Operation {
public double numberA=0;
public double numberB=0;
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public double getResult(){
double result=0;
return result;
}
}
class OperationAdd extends Operation{
public double getResult(){
double result=0;
result=numberA+numberB;
return result;
}
}
class OperationSub extends Operation{
public double getResult(){
double result=0;
result=numberA-numberB;
return result;
}
}
class OperationMul extends Operation{
public double getResult(){
double result=0;
result=numberA*numberB;
return result;
}
}
class OperationDiv extends Operation{
public double getResult(){
double result=0;
if(numberB==0)
throw new RuntimeException("除数不能为0");
result=numberA/numberB;
return result;
}
}
//工厂类
class OperationFactory{
public static Operation createOperate(String operate){
Operation oper=null;
switch(operate){
case "+":
oper=new OperationAdd();
break;
case "-":
oper=new OperationSub();
break;
case "*":
oper=new OperationMul();
break;
case "/":
oper=new OperationDiv();
break;
}
return oper;
}
}
//客户端代码
public class Client{
public static void main(String[] args){
Operation oper;
oper=OperationFactory.createOperate("+");
oper.numberA=1;
oper.numberB=2;
double result=oper.getResult();
}
}
简单工厂模式的最大优点:在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除了与具体产品的依赖。但是当需求有变化的时候,需要修改工厂类,这是福修改开放了,违背了开放-封闭原则。
2,工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到子类中。它的结构图如下:
其中:
Product:定义了工厂方法所创建的对象的接口;
ConcreteProduct:具体的产品,实现了Product接口;
Creator:声明工厂方法,该方法返回一个人Product类型的对象;
ConcreteCreator:重定义工厂方法以返回一个ConcreteProduct实例;
依然以上面的计算器为例,用从工厂方法实现时,运算类及其子类不变,然后先构建一个工厂接口,然后加减乘除各自建一个具体的工厂去实现这个接口,代码如下:
interface IFactory{
Operation creatreOperation();
}
class AddFactory implements IFactory{
public Operation creatreOperation(){
return new OperationAdd();
}
}
class SubFactory implements IFactory{
public Operation creatreOperation(){
return new OperationSub();
}
}
class MulFactory implements IFactory{
public Operation creatreOperation(){
return new OperationMul();
}
}
class DivFactory implements IFactory{
public Operation creatreOperation(){
return new OperationDiv();
}
}
//客户端代码
public class Client{
public static void main(String[] args){
Operation oper=operFactory.createOperate("+");;
oper.numberA=1;
oper.numberB=2;
double result=oper.getResult();
}
}
工厂方法模式是简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。工厂方法模式把简单工厂的内部逻辑判断移到了客户端代码来进项,当想要加功能时,本来是改工厂类的,而现在是修改客户端。但工厂方法模式的缺点是由于每加一个产品,就需要加一个产品工厂类,增加了额外的开销;
3.抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。结构图如下:
其中:
AbstractFactory:抽象工厂角色,它与程序无关,是具体工厂角色必须实现的接口或者必须继承的接口,在java中它由抽象类或者接口来实现;
ConcreteFactory:具体工厂角色:它含有与具体业务逻辑有光的代码,由应用程序调用以创建对应的具体产品对象,在java中它由具体的类来实现;
AbstractProduct:抽象产品角色:它是具体产品继承的父类或者实现的接口,在java中一般有抽象类或者接口来实现;
ConcreteProduct:具体产品角色:具体工厂角色所创建到额对象就是此角色的实例,在java中由具体的类来实现;
用一个手机类来举例子:其中有Apple手机和Andriod手机,Apple和Android又各自有Mini型的和Big型的。
//抽象产品类
abstract class ApplePhone{
private String name;
public abstract void call();
}
class MiniApple extends ApplePhone{
public void call(){
System.out.println("MiniApple");
}
}
class BigApple extends ApplePhone{
public void call(){
System.out.println("BigApple");
}
}
abstract class AndroidPhone{
private String name;
public abstract void call();
}
class MiniAndroid extends AndroidPhone{
public void call(){
System.out.println("MiniAndroid");
}
}
class BigAndroid extends AndroidPhone{
public void call(){
System.out.println("BigAndroid");
}
}
//抽象工厂
abstract class Call{
public abstract ApplePhone createApplePhone(String phone);
public abstract AndroidPhone createAndroidPhone(String phone);
}
//具体工厂
class MiniCall extends Call{
public ApplePhone createApplePhone(String phone){
return new MiniApple();
}
public AndroidPhone createAndroidPhone(String phone){
return new MiniAndroid();
}
}
class BigCall extends Call{
public ApplePhone createApplePhone(String phone){
return new BigApple();
}
public AndroidPhone createAndroidPhone(String phone){
return new BigAndroid();
}
}
//客户端
public class Client{
public static void main(String[] args){
Call c=new BigCall();
ApplePhone phone=c.createApplePhone(" ");
phone.call();
}
}
抽象工厂模式的优点:易于交换产品系列,让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例的,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。一般用于具有产品树和产品族的场景下。
缺点:如需要增加产品树,那么就要增加新的多个产品类,还要修改产品类对应的多个产品工厂类。所以又提出用简单工厂配合反射来进行改进的方法。
前面部分都不变动,只是改动了工厂类:
class Call{
public static ApplePhone createApplePhone(String phone) throws Exception{
return (ApplePhone)Class.forName(phone).newInstance();
}
public static AndroidPhone createAndroidPhone(String phone) throws Exception{
return (AndroidPhone)Class.forName(phone).newInstance();
}
}
//客户端
class Client{
public static void main(String[] args) throws Exception{
ApplePhone phone=Call.createApplePhone("com.java.factory.MiniApple");
phone.call();
}
}