设计模式(2)- 工厂模式

工厂模式作为建造类型模式的一种,工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。

1. 简单工厂模式

        简单工厂由名称就知道最为简单,其只对具体的产品做一层很薄的封装,根据指定的类型来创建对象,idea画出的UML类型:

 手机接口规范:

package com.patten.factory;

public interface Phone {
    void desc();
}

实现厂商:

package com.patten.factory.product;

import com.patten.factory.Phone;

public class IPhone implements Phone {

    public IPhone() {
        this.desc();
    }

    @Override
    public void desc() {
        System.out.println("苹果手机制造成功!");
    }
}
package com.patten.factory.product;

import com.patten.factory.Phone;

public class MiPhone implements Phone {

    public MiPhone() {
        this.desc();
    }

    @Override
    public void desc() {
        System.out.println("小米手机制造成功!");
    }
}

简单工厂:

public class PhoneSimpleFactory {

    public static Phone makePhone(String phoneName) {
        if ("xiaomi".equalsIgnoreCase(phoneName)) {
            return new MiPhone();
        } else if ("iphone".equalsIgnoreCase(phoneName)) {
            return new IPhone();
        }
        throw new RuntimeException("工厂暂时生成不了该类型手机!");
    }
}

客户端:

public class SimpleFacClient {
    public static void main(String[] args) {
        //简单工厂
        Phone xiaomi = PhoneSimpleFactory.makePhone("xiaomi");
        Phone iphone = PhoneSimpleFactory.makePhone("iphone");
    }
}

2. 工厂方法模式(Factory Method)

        工厂方法就不在想简单工厂一样直接面对具体的产品,而是面对具体的工厂,在产品种类单一的情况下我们称之为工厂方法模式。

class依赖图:

工厂规范:

public abstract class AbstractPhoneFactory {
    //生产手机工厂
    abstract Phone createPhone();
}

具体的工厂实现:

public class IPhoneFactory extends AbstractPhoneFactory {

    @Override
    public Phone createPhone() {
        return new IPhone();
    }
}
public class MiPhoneFactory extends AbstractPhoneFactory {

    @Override
    public Phone createPhone() {
        return new MiPhone();
    }
}

客户端示例:

public class Demo {

    public static void main(String[] args) {
        //根据不同的工厂制造手机
        MiPhoneFactory xiaomiFac = new MiPhoneFactory();
        IPhoneFactory iphoneFac = new IPhoneFactory();
        xiaomiFac.createPhone();
        iphoneFac.createPhone();
    }
}

3.抽象工厂模式

        工厂旨在创建生产对象,对于工厂方法模式,生产的都是单一的产品,但是若我们想再生产另一件产品,例如我们已经有手机工厂方法,但是我们此时又想生产耳机,按照工厂方法的方式,那么我们需要再新建抽象类,新的实现,这虽然满足单一职责原则,但是也使类过多,在分析单一职责原则的时候,我们也可以用在方法层面的单一职责。

        因此我们可以采用复用原则,在抽象工厂中新增生产耳机的方法。这样每个工厂又可以生产手机和耳机。

UML图:

 新增耳机产品:

public interface Headset {
    void desc();
}

苹果耳机:

public class IHeadset implements Headset {

    public IHeadset() {
        this.desc();
    }

    public void desc() {
        System.out.println("生产苹果耳机!");
    }
}

小米耳机:

public class MiHeadset implements Headset {
    public MiHeadset() {
        this.desc();
    }
    public void desc() {
        System.out.println("生产小米耳机!");
    }
}

抽象工厂规范:

public abstract class AbstractPhoneFactory {
    //生产手机工厂
    abstract Phone createPhone();

    //生产耳机
    Headset createHeadset(){
        throw new RuntimeExcetion("不支持的产品");
    }
}

苹果工厂:

public class IPhoneFactory extends AbstractPhoneFactory {
    @Override
    public Phone createPhone() {
        return new IPhone();
    }
    @Override
    Headset createHeadset() {
        return new IHeadset();
    }
}

小米工厂:

public class MiPhoneFactory extends AbstractPhoneFactory {
    @Override
    public Phone createPhone() {
        return new MiPhone();
    }
    @Override
    Headset createHeadset() {
        return new MiHeadset();
    }
}

示例:

public class Demo {

    public static void main(String[] args) {
        //根据不同的工厂制造手机
        MiPhoneFactory xiaomiFac = new MiPhoneFactory();
        IPhoneFactory iphoneFac = new IPhoneFactory();
        xiaomiFac.createPhone();
        iphoneFac.createPhone();
        
        //耳机
        Headset mi = xiaomiFac.createHeadset();
        Headset iphoneFacHeadset = iphoneFac.createHeadset();
    }
}
小结
1) 工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的 依赖关系的解耦。从而提高项目的扩展和维护性。
2) 三种工厂模式 ( 简单工厂模式、工厂方法模式、抽象工厂模式 )
3) 设计模式的依赖抽象 原则
 创建对象实例时,不要直接 new , 而是把这个 new 类的动作放在一个工厂的方法 中,并返回。有的书上说,变量不要直接持有具体类的引用。
 不要让类继承具体类,而是继承抽象类或者是实现interface( 接口 )
 不要覆盖基类中已经实现的方法
% 本工具箱主要包含三部分内容 % (支持平台MATLAB5.3或5.2,Symbolic math,optim,spline,stats) % 1. MATLAB常用数学建模工具的中文帮助 % 2. 贡献MATLAB数学建模工具(打*号) % 3. 中国大学生数学建模竞赛历年试题MATLAB程序 % % 安装步骤 % 1. 将MATHMODL.zip解压缩至matlab11\toolbox\; % 2. 启动Matlab,利用Path Browser中的Add path菜单将 % matlab11\toolbox\mathmodl增至path中,放在最前面,并保存设置; % 3. 回到你的工作目录。现在MATHMODL已成为一个普通的工具箱了。 % % 可以使用命令help mathmodl查看内容或直接用命令mathmodl学习教程。 % % 数据拟合 % interp1 - 一元函数插值 % spline - 样条插值 % polyfit - 多项式插值或拟合 % curvefit - 曲线拟合 % caspe - 各种边界条件的样条插值 % casps - 样条拟合 % interp2 - 二元函数插值 % griddata - 不规则数据的二元函数插值 % *interp - 不单调节点插值 % *lagrange - 拉格朗日插值法 % % 方程求根 % inv - 逆矩阵 % roots - 多项式的根 % fzero - 一元函数零点 % fsolve - 非线性方程组 % solve - 符号方程解 % *newton - 牛顿迭代法解非线性方程 % %微积分和微分方程 % diff - 差分 % diff - 符号导函数 % trapz - 梯形积分法 % quad8 - 高精度数值积分 % int - 符号积分 % dblquad - 矩形域二重积分 % ode45 - 常微分方程 % dsolve - 符号微分方程 % *polyint - 多项式积分法 % *quadg - 高斯积分法 % *quad2dg - 矩形域高斯二重积分 % *dblquad2 - 非矩形域二重积分 % *rk4 - 常微分方程RungeKutta法 % %随机模拟和统计分析 % max,min - 最大,最小值 % sum - 求和 % mean - 均值 % std - 标准差 % sort - 排序(升序) % sortrows - 按某一列排序(升序) % rand - [0,1]区间均匀分布随机数 % randn - 标准正态分布随机数 % randperm - 1...n 随机排列 % regress - 线性回归 % classify - 统计聚类 % *trim - 坏数据祛除 % *specrnd - 给定分布律随机数生成 % *randrow - 整行随机排列 % *randmix - 随机置换 % *chi2test - 分布拟合度卡方检验 % % 数学规划 % lp - 线性规划 % linprog - 线性规划(在MATLAB5.3使用) % fmin - 一元函数极值 % fminu - 多元函数极值拟牛顿法 % fmins - 多元函数极值单纯形搜索法 % constr - 非线性规划 % fmincon - 非线性规划(在MATLAB5.3使用) % % 离散优化 % *enum - 枚举法 % *monte - 蒙特卡洛法 % *lpint - 线性整数规划 % *L01p_e - 0-1整数规划枚举法 % *L01p_ie - 0-1整数规划隐枚举法 % *bnb18 - 非线性整数规划(在MATLAB5.3使用) % *bnbgui - 非线性整数规划图形工具(在MATLAB5.3使用) % *mintreek - 最小生成树kruskal算法 % *minroute - 最短路dijkstra算法 % *krusk - 最小生成树kruskal算法mex程序 % *dijkstra - 最短路dijkstra算法mex程序 % *dynprog - 动态规划 % % % 图形 % plot - 平面曲线(一元函数) % plot3 - 空间曲线 % mesh - 空间曲面(二元函数) % *meshf - 非矩形网格图 % *draw - 用鼠标划光滑曲线 % %中国大学生数学建模竞赛题解 % jm96a - 捕鱼策略 % jm96b - 节水洗衣机 % jm96bfun - 节水洗衣机优化函数 % jm97a - 零件参数设计 % jm97afun - 零件参数函数 % jm97aoptim - 零件参数设计优化函数 % jm97b - 截断切割 % jm97bcount - 截断切割枚举法 % jm97brule - 截断切割优化准则 % jm98a1 - 风险投资模型求解 % jm98a2 - 风险投资模型讨论 % jm98a3 - 收益与风险非线性模型求解 % jm98a3fun - 收益与风险非线性模型优化函数 % jm98b - 灾情巡视路线(C程序) % jm99a1 - 自动化车床模型一 % jm99a1fun - 自动化车床模型目标函数 % jm99a1simu - 自动化车床模型随机模拟 % jm99asmfun - 自动化车床模型费用函数 % % 演示程序 % funtool - 函数计算器 % tutdemo - MATLAB优化工具箱教程 % mathmodl - 数学建模工具箱演示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值