工厂模式:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。
与简单工程的不同:简单工功工厂哟一个factory类用于根据传入的条件,动态生成相应的实例化类并返回,这样一来,逻辑集中在类中,如果需要添加功能,那种能修改代码,不符合开闭原则,工厂方法将factory的逻辑解耦,分解成n个具体小工厂,由客户端根据需要用小工厂创建具体类,这样再以后的修改中,就不用修改源码,只用添加新的类,新的工厂实现,复合开闭原则。
优点:
在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
工厂方法要创建产品对象,也就是需要选择具体产品对象,并创建其实例,因此具体产品对象与工厂方法是耦合的。
工厂方法适用场景
1、一个类不知道它所需要的对象的类。在工厂方法模式中,我们不需要具体产品的类名,我们只需要知道创建它的具体工厂即可。
2、一个类通过其子类来指定创建那个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
3、将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。
总结
1、工厂方法模式完全符合“开闭原则”。
2、工厂方法模式使用继承,将对象的创建委托给子类,通过子类实现工厂方法来创建对象。
3、工厂方法允许类将实例化延伸到子类进行。
4、工厂方法让子类决定要实例化的类时哪一个。在这里我们要明白这并不是工厂来决定生成哪种产品,而是在编写创建者类时,不需要知道实际创建的产品是哪个,选择了使用哪个子类,就已经决定了实际创建的产品时哪个了。
5、在工厂方法模式中,创建者通常会包含依赖于抽象产品的代码,而这些抽象产品是、由子类创建的,创建者不需要真的知道在制作哪种具体产品。
简单工厂跟工厂方法不同点在与,简单工厂的factory类,用switch方法判断,增加了逻辑,这样我们在增加新的功能时候,factory类是要修改内部的,这违背了开闭原则。所以使用工厂方法,将factory作为抽象父类,然后对于每个操作都写一个产生该操作类的具体方法工厂。虽然代码量增加,但是却符合设计模式基本原则,开闭原则以及降低了耦合度。
package package0416;
import java.util.Scanner;
//运算父类,abstract抽象修饰符,不可以跟static,private,final同时修饰方法或者类
//abstract不能修饰局部变量或者成员变量以及构造方法
abstract class Operation {//运算抽象类,定义抽象方法,用于子类重载。
private double NumbBerA = 0;
private double NumberB = 0;
public Operation() {
}
public double getNumbBerA() {
return NumbBerA;
}
public void setNumbBerA(double numbBerA) {
NumbBerA = numbBerA;
}
public double getNumberB() {
return NumberB;
}
public void setNumberB(double numberB) {
NumberB = numberB;
}
public abstract void getResult();
}
//以下为加减乘除四各类,采用继承方法,重写GertResult方法,并返回result(double类型)
class OperationAdd extends Operation {
@Override
public void getResult() {
// TODO Auto-generated method stub
double result = 0;
result = this.getNumbBerA() + this.getNumberB();
System.out.println(result);
}
}
class OperationSub extends Operation {
@Override
public void getResult() {
// TODO Auto-generated method stub
double result = 0;
result = this.getNumbBerA() - this.getNumberB();
System.out.println(result);
}
}
class OperationMul extends Operation {
@Override
public void getResult() {
// TODO Auto-generated method stub
double result = 0;
result = this.getNumbBerA() * this.getNumberB();
System.out.println(result);
}
}
class OperationDiv extends Operation {
@Override
public void getResult() {
// TODO Auto-generated method stub
double result = 0;
if(this.getNumberB()==0){
System.out.println("除数不能为0");
return;
}
result = this.getNumbBerA() / this.getNumberB();
System.out.println(result);
}
}
abstract class OperationFactory {
public abstract Operation createOperation();
}
class AddFactory extends OperationFactory{
@Override
public Operation createOperation() {
// TODO Auto-generated method stub
return new OperationAdd() ;
}
}
class SubFactory extends OperationFactory{
@Override
public Operation createOperation() {
// TODO Auto-generated method stub
return new OperationSub() ;
}
}
class MulFactory extends OperationFactory{
@Override
public Operation createOperation() {
// TODO Auto-generated method stub
return new OperationMul() ;
}
}
class DivFactory extends OperationFactory{
@Override
public Operation createOperation() {
// TODO Auto-generated method stub
return new OperationDiv() ;
}
}
public class SimpleFactory {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
System.out.println("输入数字A");
double A=in.nextDouble();
System.out.println("输入数字B");
double B=in.nextDouble();
//比如做加法
OperationFactory of=new AddFactory();
Operation o=of.createOperation();
o.setNumbBerA(A);
o.setNumberB(B);
o.getResult();
}
}