设计模式之工厂模式

工厂模式可以将对象的使用和创建分离
创建对象的设计模式

一般使用的工厂模式共有三种

  • 简单工厂模式,根据参数的不同返回不同的实例。
  • 工厂方法模式,即通过工厂子类来确定究竟应该实例化哪一个具体产品。
  • 抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

这些概念等会儿可以通过代码清晰展示出来

首先实际问题

现在有两种牌子的产品,其中海尔可以生产海尔牌的电视机、海尔牌的空调,TCL可以生产TCL牌电视机、TCL牌空调。现在需要生产其中一个产品。

对于这个问题,可以选择任一工厂模式。

三种模式对比如下

类图及代码

1)简单工厂
在这里插入图片描述

 interface Product {
    void play();
}

class HairTv implements Product {

    @Override
    public void play() {
        System.out.println("HairTV播放中~");
    }
}
class TCLTv implements Product {

    @Override
    public void play() {
        System.out.println("HairTV播放中~");
    }
}

class HairAirConditioner implements Product{

    @Override
    public void play() {
        System.out.println("HairAirConditioner调温中~");
    }
}

class TCLAirConditioner implements Product{

    @Override
    public void play() {
        System.out.println("TCLAirConditioner调温中~");
    }
}
class Factory {
    public static Product produceProduct(String brand) {
        if (brand.equalsIgnoreCase("HairTv")) {
            System.out.println("生产海尔电视");
            return new HairTv();
        } else if (brand.equalsIgnoreCase("TCLTv")) {
            System.out.println("生产TCL电视");
            return new TCLTv();
        }else if(brand.equalsIgnoreCase("HairAirConditioner")) {
            System.out.println("生产海尔空调");
            return new HairAirConditioner();
        } else if(brand.equalsIgnoreCase("TCLAirConditioner")){
            System.out.println("生产TCL空调");
            return new TCLAirConditioner();
        } else {
            System.out.println("不支持生产该产品~");
        }
        return null;
    }
}
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        //根据参数的不同返回不同的实例
        Product hairTv = Factory.produceProduct("HairTv");
        if (hairTv != null) {
            hairTv.play();
        }
        System.out.println("--------------------");
        Product tclAirConditioner = Factory.produceProduct("TCLAirConditioner");
        if (tclAirConditioner != null) {
            tclAirConditioner.play();
        }
        System.out.println("--------------------");
        Product product = Factory.produceProduct("xxx");
        if (product != null) {
            product.play();
        }
    }
}

在这里插入图片描述

2)工厂方法
在这里插入图片描述
高级抽象层

//电视
public interface TV {
    void play();
}
//空调
public interface AirConditioner {
    void play();
}
//电视工厂
public interface AirConditionerFactory {
    AirConditioner produceAirConditioner();
}
//空调工厂
public interface TVFactory {
    TV productTV();
}

海尔产品

//电视
public class HairTV implements TV {
    @Override
    public void play() {
        System.out.println("海尔电视播放中...");
    }
}
//电视具体工厂
public class HairTVFactory implements TVFactory {
    @Override
    public TV productTV() {
        System.out.println("生产海尔电视机");
        return new HairTV();
    }
}
//空调
public class HairAirConditioner implements AirConditioner{
    @Override
    public void play() {
        System.out.println("海尔空调调温中~");
    }
}
//空调具体工厂
public class HairAirConditionerFactory implements AirConditionerFactory{
    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("生产海尔空调");
        return new HairAirConditioner();
    }
}

TCL产品

//电视
public class TCLTV implements TV {
    @Override
    public void play() {
        System.out.println("TCL电视播放中...");
    }
}
//电视具体工厂
public class TCLTVFactory implements TVFactory {
    @Override
    public TV productTV() {
        System.out.println("生产TCL电视");
        return new TCLTV();
    }
}
//空调
public class TCLAirConditioner implements AirConditioner{
    @Override
    public void play() {
        System.out.println("TCL空调调温中~");
    }
}
//空调具体工厂
public class TCLAirConditionerFactory implements AirConditionerFactory{
    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("生产TCL空调");
        return new TCLAirConditioner();
    }
}

demo展示

public class FactoryMethodDemo {
    public static void main(String[] args) {
        TV tv;
        AirConditioner airConditioner;
        TVFactory tvFactory = new HairTVFactory();
        AirConditionerFactory airConditionerFactory = new TCLAirConditionerFactory();

        tv = tvFactory.productTV();
        if (tv != null) {
            tv.play();
        }
        System.out.println("-------------------");
        airConditioner = airConditionerFactory.produceAirConditioner();
        if (airConditioner != null) {
            airConditioner.play();
        }
    }
}

在这里插入图片描述

3)抽象工厂
在这里插入图片描述
高级抽象层

//电视
public interface Television {
    void play();
}
//空调
public interface AirConditioner {
    void changeTemperature();
}
//工厂
public interface EFactory {
    Television produceTelevision();
    AirConditioner produceAirConditioner();
}

海尔产品

public class HairFactory implements EFactory{
    @Override
    public Television produceTelevision() {
        System.out.println("生产海尔电视");
        return new HairTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("生产海尔空调");
        return new HairAirConditioner();
    }
}
public class HairTelevision implements Television{
    @Override
    public void play() {
        System.out.println("海尔电视播放中...");
    }
}
public class HairAirConditioner implements AirConditioner {
    @Override
    public void changeTemperature() {
        System.out.println("海尔空调正在调控温度...");
    }
}

TCL产品

public class TCLFactory implements EFactory{
    @Override
    public Television produceTelevision() {
        System.out.println("生产TCL电视");
        return new TCLTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("生产TCL空调");
        return new TCLAirConditioner();
    }
}
public class TCLTelevision implements Television {
    @Override
    public void play() {
        System.out.println("TCL电视播放中...");
    }
}
public class TCLAirConditioner implements AirConditioner {
    @Override
    public void changeTemperature() {
        System.out.println("TCL空调正在调控温度中...");
    }
}

demo展示

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        EFactory eFactory;
        Television television;
        AirConditioner airConditioner;

        eFactory = new TCLFactory();

        television = eFactory.produceTelevision();
        airConditioner = eFactory.produceAirConditioner();
        television.play();
        airConditioner.changeTemperature();

        System.out.println("-----------");

        eFactory = new HairFactory();

        television = eFactory.produceTelevision();
        airConditioner = eFactory.produceAirConditioner();
        television.play();
        airConditioner.changeTemperature();
    }
}

在这里插入图片描述
可以看出,简单工厂使用简单,工厂方法如果一家公司(如海尔)生产多个产品类就会爆炸式增长,抽象工厂适用于多个产品的创建。

三种模式优缺点

1)简单工厂
优点:实现简单、使用简单
缺点:不符合开闭原则,增加新类或删除原有的产品类需要改动源代码
2)工厂方法
优点:增加类时无需修改源代码,符合开闭原则
缺点:添加新厂品时,还要添加相应的工厂类,实现复杂。
3)抽象工厂
优点:增加新的产品族很方便,无须修改已有系统,符合“开闭原则”
缺点:增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。

XML跟工厂模式搭配

比如工厂方法模式的xml配置文件使用
1)methodFactory.xml
表示生产的是Hair电视,想生产其它的,只要将配置文件中的类名修改了即可

<?xml version="1.0"  ?>
<config>
    <className>HairTVFactory</className>
</config>

2)读取xml文件的类:XMLUtil.java文件

public class XMLUtil {

    public static Object getBean() {
        try {
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            //配置文件methodFactory.xml的完整路径
            String path = "D:/java代码/twigs/src/year2020/designpattern/greational/factorymethod/methodFactory.xml";
            Document doc = builder.parse(new File(path));

            NodeList n1 = doc.getElementsByTagName("className");
            Node classNode = n1.item(0).getFirstChild();
            //cName返回的是工厂类的名字,如HairTVFactory、TCLAirConditioner,只需要修改methodFactory.xml文件即可
            String cName = classNode.getNodeValue();

            //工厂类的全限定名
            String className = "year2020.designpattern.greational.factorymethod." + cName;
            Class<?> c = Class.forName(className);
            return c.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

3)代码展示

public class FactoryMethodDemo {
    public static void main(String[] args) {
        TV tv;
        TVFactory tvFactory;
        tvFactory = (TVFactory) XMLUtil.getBean();
        if (tvFactory != null) {
            tv = tvFactory.productTV();
            tv.play();
        }
    }
}

在这里插入图片描述

4)生产TCL电视
在这里插入图片描述

5)温馨提示
对象创建跟Spring搭配食用,效果更加哦~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值