设计模式之工厂模式

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

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

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

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

首先实际问题

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

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

三种模式对比如下

类图及代码

1)简单工厂
设计模式之工厂模式_第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张图片

2)工厂方法
设计模式之工厂模式_第3张图片
高级抽象层

//电视
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();
        }
    }
}

设计模式之工厂模式_第4张图片

3)抽象工厂
设计模式之工厂模式_第5张图片
高级抽象层

//电视
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();
    }
}

设计模式之工厂模式_第6张图片
可以看出,简单工厂使用简单,工厂方法如果一家公司(如海尔)生产多个产品类就会爆炸式增长,抽象工厂适用于多个产品的创建。

三种模式优缺点

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

XML跟工厂模式搭配

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


<config>
    <className>HairTVFactoryclassName>
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();
        }
    }
}

设计模式之工厂模式_第7张图片

4)生产TCL电视
设计模式之工厂模式_第8张图片

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

你可能感兴趣的:(设计模式)