工厂和抽象工厂有些类似,有的人将工厂模式划为抽象工厂模式的一个特例
简单工厂模式
背景:输入两个数进行计算
需要的类
- 一个基础的运算类(Operation):
分别有两个运算参数和一个运算的方法(getResult) - 具体的运算类(+ - /):
*继承基础的运算类,然后重写运算的方法进行计算。 - 简单工厂的类(OperationFactory):
在工厂类里面建一个方法,用方法的参数来判断,具体实例化哪个具体的运算类。 - Main方法:
运算类
public class Operation {
// 方便于子类使用
protected double number_a;
protected double number_b;
// @Description: 在子类重写该方法用于计算结果
public double getResult() throws Exception {
double result = 0;
return result;
}
}
具体的运算类
加减乘除,我这只提供除法类的
public class OperationDiv extends Operation{
//重写计算的方法
@Override
public double getResult() throws Exception {
if(number_b == 0){
throw new Exception("除数不能为:0");
}
return number_a/number_b + number_a%number_b;
}
}
计算器工厂
public class OperationFactory {
//静态方法方便调用
public static Operation createOpection(String operate) throws Exception {
// 预设一个计算器类的父类对象:这样做可以让他少创建几个对象
Operation oper = null;
//不使用if语句,可以少做几次判断
switch (operate){
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
throw new Exception("请输入正确的运算符:" + operate);
}
return oper;
}
}
使用
- 先创建相应的对象,
- 给参数赋值
- 调用他们父类的方法(都会重写的方法来计算)
- 新增一个运算方法只需要,只需要新增一个子类,再只修改简单工厂类就行了
public static void main(String[] args) throws Exception {
Operation oper;
oper = OperationFactory.createOpection("/");
oper.number_a = 1.3;
oper.number_b = 0;
double result = oper.getResult();
System.out.println(result);
}
工厂模式
工厂模式,对于每一个点都要去创建一个工厂类。客户在使用的时候就直接去选择相应的工厂,而不需要在代码上判断选择哪个工厂。
克服了简单工厂违反开放封闭的原则的缺点,利用了多态性,保持简单工厂的优点,但是每次创建一个工厂,增加了开发量。
背景:学雷锋做好事;
- 一个雷锋工厂的接口:
包含一个创建的方法,用于实例化对象。 - 一个雷锋的产品类:
包含了相应的一些方法,方法块可以为空,也可以有默认的方法块。 - 具体的产品类继承雷锋的产品类:
重写雷锋产品类的方法块,不重写的话就调用父类的方法。 - 具体的产品工厂类,实现工厂接口类:
实现父类方法:实例化相应的产品类。 - Main:
雷锋工厂接口
public interface IFactory {
public LeiFeng CreateLiFeng();
}
雷锋产品类(父类)
public class LeiFeng {
//方法的代码块可以为空
public void Sweep(){}
public void Wash(){
System.out.println("洗衣");
}
public void BuyRice(){
System.out.println("买菜");
}
}
具体类
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("学雷锋的大学生::买菜");
}
}
具体工厂类
public class UndergraduateFactory implements IFactory {
@Override
public LeiFeng CreateLiFeng() {
return new Undergraduate();
}
}
Main
我们在使用的时候,不需要考虑调用的是哪个类。先实例化一个工厂接口,然后调用创建的方法。因为返回的都是父类所以,不在父类的方法是使用不了的。
public class FactoryMain {
public static void main(String[] args){
IFactory factory = new UndergraduateFactory();
LeiFeng student = factory.CreateLiFeng();
student.Sweep();
student.BuyRice();
student.Wash();
}
}
抽象工厂模式
抽象工厂和工厂模式有些类似,抽象工厂的工厂接口和方法以及相应的产品父类都是抽象。
工厂模式是接口,抽象工厂是抽象类
- 抽象工厂类:
包含一个抽象的返回值为抽象产品的方法(没有实现方法内容),作为子工厂类实例化相应的产品类。 - 抽象产品类:
包含一个抽象的方法,同样没有代码实现块。 - 具体产品类:
继承抽象产品类并且重写抽象方法。 - 具体的工厂:
继承抽象工厂类,重写实例化产品类的方法。可以继续写其他的类 - Main方法调用:
调用其实和工厂模式一样。
抽象产品类
public abstract class Product {
public abstract void show();
}
抽象工厂类
public abstract class Factory {
public abstract Product Manufacture();
}
具体产品类
public class ProductA extends Product{
@Override
public void show() {
System.out.println("生产产品A");
}
}
具体工厂类
public class FactoryA extends Factory{
@Override
public Product Manufacture() {
return new ProductA();
}
}
调用
public class AbstarctFactoryA {
public static void main(String[] args) {
//一般是通过抽象父类而不是具体的工厂类
//这种调用就和没使用设计模式一样的
FactoryA factoryA =new FactoryA();
factoryA.Manufacture().show();
factoryA.Men();
System.out.println("---------------------------------------");
FactoryB factoryB = new FactoryB();
factoryB.Manufacture().show();
//正常的抽象模式调用方法
Factory factoryAA = new FactoryA();
Product product = factoryAA.Manufacture();
product.show();
//偷懒的调用
factoryAA.Manufacture().show();
}
}