工厂方法模式
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到其子类。
Product:定义工厂方法所创建的对象的接口
ConcreteProduct:具体的产品,实现Product接口
Creator:声明工厂方法,返回Product类型的对象
ConcreteCreator:重定义工厂方法,返回一个ConcreteProduct
代码实现
Creator类:抽象工厂
/**
* 工厂方法
* @author xukai
* 2016年3月9日 上午10:59:29
*/
public interface Creator {
/**
* 返回Product类型对象
*/
public Product factoryMethod();
}
ConcreteCreator类:具体工厂,生产具体对象
/**
* 具体工厂,生产具体对象
* @author xukai
* 2016年3月9日 上午11:00:14
*/
public class ConcreteCreator implements Creator {
@Override
public Product factoryMethod() {
return new ConcreteProduct();
}
}
Product类:工厂生产抽象对象
/**
* 工厂方法创建对象的接口
* @author xukai
* 2016年3月9日 上午10:58:43
*/
public abstract class Product {
public abstract void show();
}
ConcreteProduct类:具体工厂生产的具体对象
/**
* 工厂具体生成的产品
* @author xukai
* 2016年3月9日 上午10:59:11
*/
public class ConcreteProduct extends Product {
@Override
public void show() {
System.out.println("ConcreteProduct展示");
}
}
客户端:
public class FactoryMethodClient {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.factoryMethod();
product.show();
}
}
控制台输出:
ConcreteProduct展示
demo1
问题: 使用Java面向对象语言实现计算器控制台程序
结构图:
代码实现
抽象工厂IFactory:
public interface IFactory {
public Operation createOpera();
}
具体工厂AddFactory:
/**
* 加法工厂
* @author xukai
* 2016年3月9日 上午11:08:35
*/
public class AddFactory implements IFactory {
@Override
public Operation createOpera() {
return new OperationAdd();
}
}
/**
* 减法工厂
* @author xukai
* 2016年3月9日 上午11:09:27
*/
public class SubFactory implements IFactory {
@Override
public Operation createOpera() {
return new OperationSub();
}
}
/**
* 乘法工厂
* @author xukai
* 2016年3月9日 上午11:09:16
*/
public class MulFactory implements IFactory {
@Override
public Operation createOpera() {
return new OperationMul();
}
}
/**
* 除法工厂
* @author xukai
* 2016年3月9日 上午11:08:45
*/
public class DivFactory implements IFactory {
@Override
public Operation createOpera() {
return new OperationDiv();
}
}
抽象运算类:
/**
*
* @author xukai
* 2016年3月9日 上午11:11:30
*/
public class Operation {
private double numberA;
private double numberB;
public double getResult(){
double result = 0.0;
return result;
}
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 class OperationAdd extends Operation {
@Override
public double getResult() {
return getNumberA()+getNumberB();
}
}
public class OperationSub extends Operation {
@Override
public double getResult() {
return getNumberA()-getNumberB();
}
}
public class OperationMul extends Operation {
@Override
public double getResult() {
return getNumberA() * getNumberB();
}
}
public class OperationDiv extends Operation {
@Override
public double getResult() {
return getNumberA() / getNumberB();
}
}
客户端测试:
public class OperationTest {
public static void main(String[] args) {
double a = 1.0;
double b = 2.0;
IFactory facotry = new AddFactory();
Operation opera = facotry.createOpera();
opera.setNumberA(a);
opera.setNumberB(b);
System.out.println(opera.getResult());
}
}
控制台输出:3.0
demo2
问题:使用工厂方法模式实现,学雷锋做好事。
抽象的工厂IFactory:
public interface IFactory {
LeiFeng createLefFeng();
}
具体的工厂,生产大学生:
public class UndergraduateFactory implements IFactory {
@Override
public LeiFeng createLefFeng() {
return new Undergraduate();
}
}
具体工厂,生产社区志愿者:
public class VolunteerFactory implements IFactory {
@Override
public LeiFeng createLefFeng() {
return new Volunteer();
}
}
大学生具体类:
/**
* 大学生
* @author xukai
* 2016年3月9日 上午11:22:24
*/
public class Undergraduate extends LeiFeng {
@Override
public void sweep() {
System.out.println("大学生扫地");
}
@Override
public void wash() {
System.out.println("大学生洗衣");
}
@Override
public void buyRice() {
System.out.println("大学生买米");
}
}
志愿者具体类:
/**
* 社区志愿者
* @author xukai
* 2016年3月9日 上午11:22:48
*/
public class Volunteer extends LeiFeng {
@Override
public void sweep() {
System.out.println("志愿者扫地");
}
@Override
public void wash() {
System.out.println("志愿者洗衣");
}
@Override
public void buyRice() {
System.out.println("志愿者买米");
}
}
客户端:
public class Client {
public static void main(String[] args) {
IFactory factory = new UndergraduateFactory();
LeiFeng student = factory.createLefFeng();
student.sweep();
student.buyRice();
student.wash();
factory = new VolunteerFactory();
LeiFeng volunteer = factory.createLefFeng();
volunteer.sweep();
volunteer.buyRice();
volunteer.wash();
}
}
控制台打印:
大学生扫地
大学生买米
大学生洗衣
志愿者扫地
志愿者买米
志愿者洗衣
大学生买米
大学生洗衣
志愿者扫地
志愿者买米
志愿者洗衣
简单工厂模式和工厂方法模式对比
1.简单工厂模式:有关简单工厂模式的内容,在前一篇博文已经有详细的介绍。(
简单工厂模式)
分析:
简单工厂模式又叫静态工厂模式,直白地来说,就是创建一个静态的方法,通过客户端中传过来的消息,判断应该实例化哪个对象,并且返回它,这样对于客户端来说,去除了与具体产品的依赖。换句话说,
逻辑判断是工厂来执行的。
demo:计算机工厂方法模式实现的结构图
缺点:违反了开闭原则,简单工厂不但对扩展开放了,对修改也开放了。如果需要再加一种运算方法,需要重新修改工厂内容。
2.工厂方法模式
降低了客户程序与产品对象的耦合,是简单工厂模式的进一步抽象和推广,使用了多态,保持了简单工厂模式的优点。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现操作,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,本来修改工厂类,转移到修改客户端。
缺点:每加一个产品,就需要加一个产品工厂类,增加了额外的开发量。