工厂模式总结(零到三)
方便理解 在来一个例子
简单小作坊型工厂
下面的例子介绍了将产品抽象以后,提供生产工厂,对产品进行销售,接受用户的定制。
但是交由一个工厂来做,越来越多的产品是不是会不专业呢。
package simple;
/**
* @author Heaton
* @date 2018/3/28 0028 22:56
* @describe 牛奶接口
*/
public interface Milk {
/**
* @author Heaton
* @date 2018/3/28 0028 22:52
* @param []
* @return java.lang.String
* @describe 提供牛奶
*/
public String getName();
}
package simple;
import simple.Milk;
/**
* @author Heaton
* @date 2018/3/28 0028 22:56
* @describe 特仑苏牛奶
*/
public class Telunsu implements Milk {
/**
* @author Heaton
* @date 2018/3/28 0028 22:56
* @param []
* @return java.lang.String
* @describe 特仑苏方法
*/
@Override
public String getName() {
return "特仑苏";
}
@Override
public String toString() {
return "Telunsu{}";
}
}
package simple;
/**
* @author Heaton
* @date 2018/3/28 0028 23:33
* @describe 伊利
*/
public class Yili implements Milk {
@Override
public String getName() {
return "伊利";
}
@Override
public String toString() {
return "Yili{}";
}
}
package simple;
/**
* @author Heaton
* @date 2018/3/28 0028 23:33
* @describe 蒙牛
*/
public class MenNiu implements Milk {
@Override
public String getName() {
return "蒙牛";
}
@Override
public String toString() {
return "MenNiu{}";
}
}
package simple;
/**
* @author Heaton
* @date 2018/3/28 0028 22:56
* @describe 简单工厂
*/
public class SimpleFactory {
public Milk getMike(String name){
if("特仑苏".equals(name)){
return new Telunsu();
}else if("伊利".equals(name)){
return new Yili();
}else if("蒙牛".equals(name)){
return new MenNiu();
}
return null;
}
}
package simple;
/**
* @author Heaton
* @date 2018/3/28 0028 22:56
* @describe 工厂测试
*/
public class SimpleFactoryTest {
public static void main(String[] args) {
//小作坊式生产模式
//用户本身不在关心生产过程,而只需要关心结果
//加入:特仑苏、伊利、蒙牛 成分比例都不同
SimpleFactory factory = new SimpleFactory();
System.out.println(factory.getMike("伊利"));
System.out.println(factory.getMike("特仑苏"));
System.out.println(factory.getMike("蒙牛"));
}
}
不专业,我们就把工厂也给抽象了。
package simple.StaticFactory;
import simple.Milk;
/**
* @author Heaton
* @date 2018/3/29 0029 15:24
* @describe 静态工厂
*/
public interface StaticFactory {
//生产产品的技能
Milk getMilk();
}
package simple.StaticFactory;
import simple.MenNiu;
import simple.Milk;
import simple.Telunsu;
/**
* @author Heaton
* @date 2018/3/29 0029 15:24
* @describe X
*/
public class MengNiuFactory implements StaticFactory{
@Override
public Milk getMilk() {
return new MenNiu();
}
}
package simple.StaticFactory;
import simple.Milk;
import simple.Telunsu;
/**
* @author Heaton
* @date 2018/3/29 0029 15:24
* @describe X
*/
public class TelunsuFactory implements StaticFactory{
@Override
public Milk getMilk() {
return new Telunsu();
}
}
package simple.StaticFactory;
import simple.MenNiu;
import simple.Milk;
import simple.Yili;
/**
* @author Heaton
* @date 2018/3/29 0029 15:24
* @describe X
*/
public class YiLiFactory implements StaticFactory{
@Override
public Milk getMilk() {
return new Yili();
}
}
package simple.StaticFactory;
/**
* @author Heaton
* @date 2018/3/29 0029 15:29
* @describe 工厂方法设计模式测试
*/
public class StaticFactoryTest {
public static void main(String[] args) {
//发现必须要让用户来选择工厂,如果客户不知道工厂就会出错。
StaticFactory staticFactory = new MengNiuFactory();
System.out.println(staticFactory.getMilk());
StaticFactory staticFactory1 = new YiLiFactory();
System.out.println(staticFactory1.getMilk());
StaticFactory staticFactory2 = new TelunsuFactory();
System.out.println(staticFactory2.getMilk());
}
}
那么用上面的方法工厂模式我们可以发现,工厂倒是专业了,可是问题来了,用户要定制产品的时候,找哪个工厂呢?很懵逼
那么能不能有一个更好的解决呢
package simple.AbsFactory;
import simple.Milk;
/**
* @author Heaton
* @date 2018/3/29 0029 15:53
* @describe 对专业的所有工厂进行抽象
*/
public abstract class AbstractFactory {
//公共的逻辑,为什么不是借口呢,是为了方便统一的管理,
//接口不能存储逻辑,而抽象类可以
//获得一个蒙牛牛奶
public abstract Milk getMenNiu();
//获得一个伊利牛奶
public abstract Milk getYili();
//获得一个特仑苏牛奶
public abstract Milk getTelunsu();
//获得一个三鹿牛奶
public abstract Milk getSanLu();
}
package simple.AbsFactory;
import simple.MenNiu;
import simple.Milk;
import simple.StaticFactory.MengNiuFactory;
import simple.StaticFactory.TelunsuFactory;
import simple.StaticFactory.YiLiFactory;
/**
* @author Heaton
* @date 2018/3/29 0029 15:57
* @describe 对专业的所有工厂进行抽象
*/
public class MilkFactory extends AbstractFactory {
@Override
public Milk getMenNiu() {
return new MengNiuFactory().getMilk();
//return new MenNiu();
//可以直接选择对象,而这里使用了混合开发(spring就是这种工厂)
//用了抽象工厂和工厂方法两种设计模式。
}
@Override
public Milk getYili() {
return new YiLiFactory().getMilk();
}
@Override
public Milk getTelunsu() {
return new TelunsuFactory().getMilk();
}
//添加一个三鹿奶粉,抽象工厂只需要升级API就可以了
//现在去实现类李添加一个三鹿牛奶
//在就是直接在抽象工厂里添加一个返回方法
//在实现这个方法重写
@Override
public Milk getSanLu() {
return new SanLu();
}
}
package simple.AbsFactory;
/**
* @author Heaton
* @date 2018/3/29 0029 15:55
* @describe X
*/
public class AbstractFactoryTest {
public static void main(String[] args) {
AbstractFactory factory = new MilkFactory();
//对于用户不需要自己而言就可以找到工厂,直接定制专业的牛奶咯。
//而用户就相当于只有选择权了,不需要输入,就不会报错咯
System.out.println(factory.getMenNiu());
System.out.println(factory.getYili());
System.out.println(factory.getTelunsu());
//添加三鹿奶粉
System.out.println(factory.getSanLu());
}
}
package simple.AbsFactory;
import simple.Milk;
/**
* @author Heaton
* @date 2018/3/29 0029 16:07
* @describe 毒奶粉
*/
public class SanLu implements Milk {
@Override
public String getName() {
return "三鹿";
}
@Override
public String toString() {
return super.toString();
}
}
注意看注释,添加了三鹿牛奶,只是简单的升级了API,而达到让用户多出选择项,达到了设计模式的开闭原则,
扩展开放,修改关闭。(增加代码,并不一定代表修改)
总结一下
简单工厂模式:对产品抽象,用户可以找到工厂定制产品,但是并不能把产品专业化,做出来的东西可能就是冒牌的。
工厂方法模式:对产品和工厂都进行抽象,不同的工厂根据配比生成不同的产品,用户在找到工厂的时候会很苦恼,但是一旦
找到,做出来的东西就会很OK。
抽象工厂方法:抽象出一个大工厂,给用户提供选择工厂的权利(接受定制的工厂),做出用户满意的产品。但是,大工厂在
管理上会耦合很多业务,对于管理不太方便。
抽象工厂+工厂方法:可以使用户有选择的权利,并且把大工厂的业务进行划分,对其下属工厂进行管理,制造出好产品。
实际应用一下,做个简单计算器
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:45 * @describe 操作 */ public abstract class Operation { private double num1; private double num2; public double getNum1() { return num1; } public void setNum1(double num1) { this.num1 = num1; } public double getNum2() { return num2; } public void setNum2(double num2) { this.num2 = num2; } public abstract double getResult(); }
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:47 * @describe 添加操作 */ public class AddOperation extends Operation { public double getResult() { double result = this.getNum1() + this.getNum2(); return result; } }
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:50 * @describe 减法操作 */ public class SubtractionOperation extends Operation { public double getResult() { double result = this.getNum1() - this.getNum2(); return result; } }
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:46 * @describe 操作工厂 */ public interface OperationFactory { public Operation getOperation(); }
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:47 * @describe 添加操作工厂 */ public class AddOperationFactory implements OperationFactory{ public Operation getOperation() { return new AddOperation(); } }
package com.tzy.FactoryApp; /** * @author Heaton * @date 2018/5/6 22:47 * @describe 减法操作工厂 */ public class SubtractionOperationFactory implements OperationFactory{ public Operation getOperation() { return new SubtractionOperation(); } }
package com.tzy.FactoryApp; import java.util.Scanner; /** * @author Heaton * @date 2018/5/6 22:44 * @describe 计算器 */ public class FactoryAppTest { public static void main(String[] args) { //1.接受控制台输入 System.out.println("---计算器程序---"); System.out.println("输入第一个操作数"); Scanner scanner = new Scanner(System.in); String strNum1 = scanner.nextLine(); System.out.println("输入运算符"); String oper = scanner.nextLine(); System.out.println("输入第二个操作数"); String strNum2 = scanner.nextLine(); double result = 0; double num1 = Double.parseDouble(strNum1); double num2 = Double.parseDouble(strNum2); //2.进行运算 OperationFactory factory; Operation operation; if ("+".equals(oper)) { factory = new AddOperationFactory(); result = getMethod(factory,num1,num2); } else if ("-".equals(oper)) { factory = new SubtractionOperationFactory(); result = getMethod(factory,num1,num2); } //3.返回结果 System.out.println(strNum1 + oper + strNum2 + "=" + result); } public static double getMethod(OperationFactory factory,double num1,double num2){ Operation operation= factory.getOperation(); operation.setNum1(num1); operation.setNum2(num2); double result = operation.getResult(); return result; } }

您的资助是我最大的动力!
金额随意,欢迎来赏!
浙公网安备 33010602011771号