设计模式笔记 -- 工厂模式

简介: 现在有一个发快递的流程要实现,如果用传统的方式实现,代码是下面这样

现在有一个发快递的流程要实现,如果用传统的方式实现,代码是下面这样


//快递抽象类
public abstract class Express {
    private String name;
    //快递下单,不同的快递需要在不同的网站下单,做成抽象
    public abstract void placeAndOrder();
    //取件方法
    public void pickUp(){
        System.out.println(name+"快递员来取件");
    }
    //发货方法
    public void sendOut(){
        System.out.println(name+"快递发出");
    }
    public void setName(String name){
        this.name = name;
    }
}
//顺丰快递
public class SFExpress extends Express{
    public SFExpress(){
        super.setName("顺丰");
    }
    @Override
    public void placeAndOrder() {
        System.out.println("在顺丰官网下单");
    }
}
//京东快递
public class JDExpress extends Express{
    public JDExpress(){
        super.setName("京东");
    }
    @Override
    public void placeAndOrder() {
        System.out.println("在京东快递官网下单");
    }
}
//快递订单类    
public class ExpressOrder {
    public ExpressOrder(String type) {
        Express express = null;
        if ("JD".equals(type)) {
            express = new JDExpress();
        } else if ("SF".equals(type)) {
            express = new SFExpress();
        }
        //过程
        express.placeAndOrder();
        express.pickUp();
        express.sendOut();
    }
}
public class ExpressTest {
    public static void main(String[] args) {
        new ExpressOrder("SF");
        System.out.println("_____________");
        new ExpressOrder("JD");
    }
}

运行测试类的结果



这样看起来是没有问题的,但是这样设计违反了开闭原则,即对扩展开放,对修改关闭。


在实际开发中,订单类可能不只有一个,如果要新增一个快递种类,需要改多处代码。



简单工厂模式

简易工厂模式属于创建型模式,是工厂模式的一种。简易工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,是工厂模式中最简单实用的模式


简易工厂模式:定义了一个创建对象的类,这个类用来封装实例化对象的代码,在开发中,当需要大量的创建某种对象,某类对象,某批对象时,就会使用到工厂模式



现在在上面的代码基础上加一个简单工厂类


//简单工厂
public class SimpleFactory {
    public Express getExpress(String type){
        Express express = null;
        if ("JD".equals(type)) {
            express = new JDExpress();
        } else if ("SF".equals(type)) {
            express = new SFExpress();
        }
        return express;
    }
}

然后在订单类中聚合这个简单工厂类

//快递订单类
public class ExpressOrder {
    private SimpleFactory simpleFactory = new SimpleFactory();
    public ExpressOrder(String type){
        Express express = simpleFactory.getExpress(type);
        express.placeAndOrder();
        express.pickUp();
        express.sendOut();
    }
}

然后使用测试类

public class ExpressTest {
    public static void main(String[] args) {
        new ExpressOrder("SF");
        System.out.println("_____________");
        new ExpressOrder("JD");
    }
}

输出的结果还是一样的


这样一来,如果要新增一个新的快递类型,只需要在工厂类里面新增一句代码,而不需要每个订单类都要修改(如果有多个订单类)


如果把工厂类中的getExpress方法改成静态方法,在订单类中就可以直接类名调用,这样就变成了静态工厂模式


工厂方法模式

还是上面的寄快递需求,现在需求变了,京东和顺丰不止有快递还有物流,可能需要发京东快递或京东物流、顺丰快递或顺丰物流


这个时候可以考虑使用工厂方法模式


设计方案:将快递对象实例化的功能抽象成抽象方法,在不同的快递子类中具体实现


即定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。



快递类不变,实现四个子类,如图



对象实例化方法放到订单类,做成抽象方法,由子类实现

//快递订单类
public abstract class ExpressOrder {
    abstract Express getExpress(String type);
    public ExpressOrder(String type){
        Express express = getExpress(type); //抽象方法,由子类完成
        express.placeAndOrder();
        express.pickUp();
        express.sendOut();
    }
}

两个订单子类

//京东快递订单类
public class JDExpressOrder extends ExpressOrder{
    public JDExpressOrder(String type) {
        super(type);
    }
    @Override
    Express getExpress(String type) {
        Express express = null;
        if("JD".equals(type)){
            express = new JDExpress();
        }else if("JDWL".equals(type)){
            express = new JDExpressWL();
        }
        return express;
    }
}


//顺丰快递订单类
public class SFExpressOrder extends ExpressOrder{
    public SFExpressOrder(String type) {
        super(type);
    }
    @Override
    Express getExpress(String type) {
        Express express = null;
        if("SF".equals(type)){
            express = new SFExpress();
        }else if("SFWL".equals(type)){
            express = new SFExpressWL();
        }
        return express;
    }
}


测试类测试

public class ExpressTest {
    public static void main(String[] args) {
        new JDExpressOrder("JD");
        System.out.println("_________________");
        new JDExpressOrder("JDWL");
        System.out.println("_________________");
        new SFExpressOrder("SF");
        System.out.println("_________________");
        new SFExpressOrder("SFWL");
    }
}

输出结果



抽象工厂模式

抽象工厂模式是把上面两种方法综合起来,工厂类使用接口,然后根据分类新建多个工厂子类。

public interface AbsFactory {
    Express getExpress(String type);
}
public class JDFactory implements AbsFactory{
    @Override
    public Express getExpress(String type) {
        Express express = null;
        if("JD".equals(type)){
            express = new JDExpress();
        }else if("JDWL".equals(type)){
            express = new JDExpressWL();
        }
        return express;
    }
}
public class SFFactory implements AbsFactory{
    @Override
    public Express getExpress(String type) {
        Express express = null;
        if("SF".equals(type)){
            express = new SFExpress();
        }else if("SFWL".equals(type)){
            express = new SFExpressWL();
        }
        return express;
    }
}

然后在订单类中组合工厂类

//快递订单类
public class ExpressOrder {
    AbsFactory factory;
    public ExpressOrder(AbsFactory factory,String type){
        Express express = factory.getExpress(type); //抽象方法,由子类完成
        express.placeAndOrder();
        express.pickUp();
        express.sendOut();
    }
}
测试
public class ExpressTest {
    public static void main(String[] args) {
        new ExpressOrder(new JDFactory(),"JD");
        System.out.println("______________");
        new ExpressOrder(new JDFactory(),"JDWL");
        System.out.println("______________");
        new ExpressOrder(new SFFactory(),"SF");
        System.out.println("______________");
        new ExpressOrder(new SFFactory(),"SFWL");
    }
}

输出结果还是一样的



在jdk中哪里使用到了工厂模式呢,Calendar类(日历类)在创建的时候,使用静态方法getInstance,使用的是简单工厂模式


工厂模式的意义:将实例化对象的代码抽取出来,放到一个类中统一管理,达到和主项目的依赖关系解耦,提高项目的扩展性和维护性。


抽象工厂模式就遵循了八大原则中的依赖倒置原则,去依赖抽象而不是依赖细节


相关文章
|
19天前
|
设计模式 Java
【设计模式系列笔记】责任链模式
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。每个处理者都有一个对下一个处理者的引用。责任链模式常用于处理请求的场景,例如在一个请求需要经过多个步骤或者多个对象来处理的情况下。
26 0
|
19天前
|
设计模式 缓存 监控
【设计模式系列笔记】代理模式
代理模式是一种结构型设计模式,它允许一个对象(代理对象)控制另一个对象的访问。代理对象通常充当客户端和实际对象之间的中介,用于对实际对象的访问进行控制、监控或其他目的。
50 1
|
17天前
|
设计模式 Java
Java一分钟之-设计模式:工厂模式与抽象工厂模式
【5月更文挑战第17天】本文探讨了软件工程中的两种创建型设计模式——工厂模式和抽象工厂模式。工厂模式提供了一个创建对象的接口,延迟实例化到子类决定。过度使用或违反单一职责原则可能导致问题。代码示例展示了如何创建形状的工厂。抽象工厂模式则用于创建一系列相关对象,而不指定具体类,但添加新产品可能需修改现有工厂。代码示例展示了创建颜色和形状的工厂。根据需求选择模式,注意灵活性和耦合度。理解并恰当运用这些模式能提升代码质量。
29 2
|
19天前
|
设计模式
【设计模式】张一鸣笔记:责任链接模式怎么用?
【设计模式】张一鸣笔记:责任链接模式怎么用?
18 1
|
19天前
|
设计模式 算法 Java
【设计模式系列笔记】设计模式与设计原则
设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 设计原则是一些通用的设计指导方针,它们提供了如何设计一个优秀的软件系统的基本思想和规则。指导着设计者如何组织代码以实现高内聚、低耦合、易扩展和易维护的软件系统。
33 4
|
19天前
|
设计模式 安全 Java
【设计模式学习】单例模式和工厂模式
【设计模式学习】单例模式和工厂模式
|
19天前
|
设计模式 Java
Java 设计模式:工厂模式与抽象工厂模式的解析与应用
【4月更文挑战第27天】设计模式是软件开发中用于解决常见问题的典型解决方案。在 Java 中,工厂模式和抽象工厂模式是创建型模式中非常核心的模式,它们主要用于对象的创建,有助于增加程序的灵活性和扩展性。本博客将详细介绍这两种模式的概念、区别以及如何在实际项目中应用这些模式。
19 1
|
19天前
|
设计模式 JavaScript 前端开发
vue的设计模式_笔记
vue的设计模式_笔记
16 0
|
19天前
|
设计模式 算法 编译器
【设计模式系列笔记】访问者模式
访问者模式是一种行为设计模式,旨在将算法与对象结构分离,使得能够在不修改元素类的前提下定义新的操作。这一模式的核心思想是在元素类中添加一个接受访问者的方法,从而实现在不同元素上执行不同操作的能力。
40 0
|
19天前
|
设计模式 SQL 算法
【设计模式系列笔记】模板方法模式
模板方法模式是一种行为设计模式,它定义了一个算法的骨架,并允许子类在不改变该算法结构的情况下重新定义算法的某些步骤。这种模式属于行为型模式,它通过将算法的不同部分封装在不同的方法中,从而使子类能够在不改变算法结构的前提下定制算法的某些步骤。
36 0