设计模式---工厂模式

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。工厂模式大体可分为三类:分别是,简单工厂模式,工厂方法模式和抽象工厂模式

简单工厂模式

简单工厂模式又称静态工厂方法模式和名字一样简单,直接上代码吧:

/**
 * 产品的抽象接口  女娲
 */
public interface NvWa {

    public void say();
}
public class Man implements NvWa{
    @Override
    public void say() {
        System.out.println("男人");
    }
}
public class Woman implements NvWa {
    @Override
    public void say() {
        System.out.println("女人");
    }
}
public class SampleFactory {
    public static NvWa makeNvWa(String type){
        if(type.equals("man")){
            NvWa man = new Man();
            return man;
        }else if(type.equals("woman")){
            NvWa women = new Woman();
            return women;
        }else{
            System.out.println("对不起不在生产范围内,生产不出来");
            return null;
        }
    }
}

简单地说,简单工厂模式通常就是这样,一个工厂类 XxxFactory,里面有一个静态方法,根据我们不同的参数,返回不同的派生自同一个父类(或实现同一接口)的实例对象。

简单工厂模式缺点:严重违反开闭原则,因为这个时候如果女王要造人妖的话,那肯定要修改工厂的方法,这就违反了开闭原则:修改关闭,对扩展开放。

工厂方法模式

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
在spring中的FactoryBean接口正是使用了工厂方法模式,FactoryBean是抽象工厂ProxyFactoryBean,DateTimeFormatterFactoryBean等是具体工厂。AopProxyDate,TimeFormatter等是具体产品。

抽象工厂:

public interface TeaWithMilkFactory {
    TeaWithMilk factory();
}

抽象产品角色:

public interface TeaWithMilk {
    void makeTea();
}

具体工厂角色:

public class OrmosiaFactory implements TeaWithMilkFactory {
    @Override
    public TeaWithMilk factory() {
        return new OrmosiaTea();
    }
}
public class YybbFactory implements TeaWithMilkFactory {
    @Override
    public TeaWithMilk factory() {
        return new YybbTea();
    }
}

具体产品角色

public class OrmosiaTea implements TeaWithMilk {
    @Override
    public void makeTea() {
        System.out.println("红豆奶茶");
    }
}
public class YybbTea implements TeaWithMilk {
    @Override
    public void makeTea() {
        System.out.println("芋圆波波奶茶");
    }
}

实际开发中抽象工厂与抽象产品常常用抽象java类来实现

抽象工厂模式

工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则。所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。当涉及到产品族的时候,抽象工厂模式就很适用。一个经典的例子是造一台电脑。我们先不引入抽象工厂模式,看看怎么实现。因为电脑是由许多的构件组成的,我们将 CPU 和主板进行抽象,然后 CPU 由 CPUFactory 生产,主板由 MainBoa rdFactory生产,然后,我们再将 CPU 和主板搭配起来组合在一起,如下图:
在这里插入图片描述
这个时候的客户端调用是这样的:

// 得到 Intel 的 CPU
CPUFactory cpuFactory = new IntelCPUFactory();
CPU cpu = intelCPUFactory.makeCPU();

// 得到 AMD 的主板
MainBoardFactory mainBoardFactory = new AmdMainBoardFactory();
MainBoard mainBoard = mainBoardFactory.make();

// 组装 CPU 和主板
Computer computer = new Computer(cpu, mainBoard);

单独看 CPU 工厂和主板工厂,它们分别是前面我们说的工厂模式。这种方式也容易扩展,因为要给电脑加硬盘的话,只需要加一个 Hard DiskFactory 和相应的实现即可,不需要修改现有的工厂。但是,这种方式有一个问题,那就是如果 Intel 家产的 CPU 和 AMD 产的主板不能兼容使用,那么这代码就容易出错,因为客户端并不知道它们不兼容,也就会错误地出现随意组合。下面就是我们要说的产品族的概念,它代表了组成某个产品的一系列附件的集合:
在这里插入图片描述
当涉及到这种产品族的问题的时候,就需要抽象工厂模式来支持了。我们不再定义 CPU 工厂、主板工厂、硬盘工厂、显示屏工厂等等,我们直接定义电脑工厂,每个电脑工厂负责生产所有的设备,这样能保证肯定不存在兼容问题。
在这里插入图片描述
这个时候,对于客户端来说,不再需要单独挑选 CPU厂商、主板厂商、硬盘厂商等,直接选择一家品牌工厂,品牌工厂会负责生产所有的东西,而且能保证肯定是兼容可用的。

public static void main(String[] args) {
    // 第一步就要选定一个“大厂”
    ComputerFactory cf = new AmdFactory();
    // 从这个大厂造 CPU
    CPU cpu = cf.makeCPU();
    // 从这个大厂造主板
    MainBoard board = cf.makeMainBoard();
      // 从这个大厂造硬盘
      HardDisk hardDisk = cf.makeHardDisk();

    // 将同一个厂子出来的 CPU、主板、硬盘组装在一起
    Computer result = new Computer(cpu, board, hardDisk);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值