场景:
建立雷锋工厂,学雷锋做好事
工厂模式:
先将之前用简单工厂实现的计算器改为工厂模式:
计算类:
package Factory3;
public class Operation {
public double numA;
public double numB;
public double getResult(){
return 0.0;
}
}
加法计算类,继承计算类:
package Factory3;
public class AddOperation extends Operation {
@Override
public double getResult() {
return numA + numB;
}
}
减法计算类,继承计算类:
package Factory3;
public class SubOperation extends Operation{
@Override
public double getResult() {
return numA - numB;
}
}
工厂接口:
package Factory3;
public interface IFactory {
Operation CreateOperation();
}
加法工厂实现工厂接口:
package Factory3;
public class AddFactory implements IFactory {
@Override
public Operation CreateOperation() {
return new AddOperation();
}
}
减法工厂实现工厂接口:
package Factory3;
public class SubFactory implements IFactory{
@Override
public Operation CreateOperation() {
return new SubOperation();
}
}
客户端:
package Factory3;
public class MainTest {
public static void main(String[] args) {
IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation();
oper.numA = 1;
oper.numB = 2;
double result = oper.getResult();
System.out.println(result);
}
}
简单工厂VS工厂方法:
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断:
public class Factory2 {
public static Operation getOperation(char ope){
switch(ope){
case '+':
return new AddOperation();
case '-':
return new SubOperation();
default:
throw new RuntimeException();
}
}
}
根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。在计算器的实现中,客户端不用管用哪个类的实例,只需要把“+”给工厂,工厂就会给出相应的实例,不同的实例会实现不同的运算。
但如果需要新加一个运算方法,需要在工厂类中添加case分支条件,修改原有的类,这违背了“开放封闭原则”,因此有了工厂方法。
工厂方法:
工厂方法中有一个工厂抽象接口和多个具体生成对象的工厂,增加其他运算功能时,不需要更改原有的工厂类,只需要增加此功能的运算类和相应的工厂类即可。
雷锋类:
package Factory_LeiFeng;
public class LeiFeng {
public void Sweep(){
System.out.println("扫地");
}
public void Wash(){
System.out.println("洗衣");
}
public void BuyRice(){
System.out.println("买米");
}
}
大学生类继承雷锋类:
package Factory_LeiFeng;
public class Undergraduation extends LeiFeng{
}
社区志愿者继承雷锋类:
package Factory_LeiFeng;
public class Volunteer extends LeiFeng {
}
雷锋工厂:
package Factory_LeiFeng;
public interface IFactory {
LeiFeng CreateLeiFeng();
}
大学生工厂实现工厂接口:
package Factory_LeiFeng;
public class UndergraduateFactory implements IFactory {
@Override
public LeiFeng CreateLeiFeng() {
return new Undergraduation();
}
}
社区志愿者工厂实现工厂接口:
package Factory_LeiFeng;
public class VolunteerFactory implements IFactory{
@Override
public LeiFeng CreateLeiFeng() {
return new Volunteer();
}
}
客户端:
package Factory_LeiFeng;
public class MainTest {
public static void main(String[] args) {
IFactory factory = new UndergraduateFactory();
LeiFeng student = factory.CreateLeiFeng();
student.BuyRice();
student.Sweep();
student.Wash();
}
}
工厂方法克服了简单工厂违背“开放-封闭原则”的缺点,又保持了封装对象创建过程的优点。要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。但缺点是由于每加一个产品,就需要添加一个产品工厂的类,增加了额外的开发量。