返回顶部
扩大
缩小

Heaton

工厂模式总结(零到三)

方便理解 在来一个例子

 

简单小作坊型工厂

下面的例子介绍了将产品抽象以后,提供生产工厂,对产品进行销售,接受用户的定制。

但是交由一个工厂来做,越来越多的产品是不是会不专业呢。

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;
    }
}

 

posted on 2018-05-11 22:45  咘雷扎克  阅读(128)  评论(0编辑  收藏  举报

导航