ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

大话设计模式:工厂模式

2020-09-11 23:03:06  阅读:199  来源: 互联网

标签:www zhangjianbing Car 大话 Author 工厂 设计模式 public


SimpleFactory

说到工厂,我们应该能想到,造汽车的有汽车工厂,造轮船的有轮船工厂,映射到Java中,造对象的就应该有对象工厂,比如说我想要买一辆车,那我只需要去汽车工厂(先不去4S店)里面告诉它什么品牌的汽车,具体参数,给钱提车就完了,我并不需要了解汽车是如何造出来的,也就是屏蔽了造车的细节,这样的好处就是对于买家来说,简单方便,用户体验大大提升,对于卖家来说我厂生产汽车的具体细节不会外露。

需求:

用户提出要圆形、三角形、菱形等等。

解决方案1:

public void m1() {
    // 用户需要圆,自己new一个
    Circle circle = new Circle();
    // 用户需要三角形,自己new一个
    Triangle triangle = new Triangle();
}

解决方案2:

可以使用简单工厂的模式,只需要将工厂暴露给调用方,调用方给出自己想要的形状就可以了,因为所有的设计模式都是面向接口编程,所以接口是少不了的。

定义一个Shape接口

/**
 * Description: 所有图形都有的公共属性,定义成抽象类也可以,接口也可
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface Shape {

    void draw();

}

Shape接口的实现类CricleShape

/**
 * Description: 圆形实例
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class CircleShape implements Shape {

    public CircleShape() {
        System.out.println("圆形创建出来。");
    }

    @Override
    public void draw() {
        System.out.println("画出一个圆形。");
    }

}

Shape接口的实现类Triangle

/**
 * Description: 三角形实例
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class TriangleShape implements Shape {

    public TriangleShape() {
        System.out.println("三角形创建出来。");
    }

    @Override
    public void draw() {
        System.out.println("画出一个三角形");
    }

}

简单工厂类,对外暴露方法

/**
 * Description: 简单工厂类
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class ShapeFactory {

    /**
     * 1. 简单工厂模式对外屏蔽了对象的创建细节,需要什么对象直接从工厂获取。
     * 2. 将获取对象的方法声明成静态的,由工厂类,向外提供服务。
     */
    public static Shape getShape(String shapeName) {
        Shape shape = null;
        if (null != shapeName && !"".equals(shapeName)) {
            if ("circle".equalsIgnoreCase(shapeName)) {
                shape = new CircleShape();
            } else if ("triangle".equalsIgnoreCase(shapeName)) {
                shape = new TriangleShape();
            }
        }
        return shape;
    }

}

测试类

在调用方只需要给工厂提供想要的形状即可,不必关心形状是如何来的。

/**
 * Description: 简单工厂模式测试用例
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class Test01 {

    @Test
    public void m1() {
        Shape circle = ShapeFactory.getShape("circle");
        circle.draw();
    }

}

简单工厂,根本来说不属于23中设计模式中的一种,但工厂方法模式和抽象工厂模式都是由它演变来的,它的缺点:系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了OCP原则。

FactoryMethod

还是上面的汽车例子,简单工厂类中维护了创建不同汽车的逻辑,比如说包括宝马,奔驰,奥迪,但后续需求越来越多,又增添了长城,马自达,大众等等品牌,那么这个工厂类的创建逻辑会越来越多,现实中,宝马有宝马自己的工厂,奔驰也有奔驰自己的工厂,映射到Java中,不同的类,应该有各自的工厂,这样的目的就是为了维护扩展方便,同时遵循了OCP原则。

设计模式是基于接口的,首先要有一个汽车的接口Car,它用来规定汽车的公共功能:

/**
 * Description: 所有汽车的公共接口
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface Car {

    /**
     * car在跑。
     */
    void running();

}

然后是具体品牌汽车的实例:

宝马:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BaoMa implements Car {

    @Override
    public void running() {
        System.out.println("宝马飞驰。");
    }

}

奔驰:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BenChi implements Car {

    @Override
    public void running() {
        System.out.println("奔驰奔跑。");
    }

}

然后是各自品牌的工厂,在创建各自工厂之前,最好加一层汽车工厂接口,目的是用多态来返回不同的工厂,使代码更加灵活。

汽车工厂接口:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface CarFactory {

    Car createCar();

}

各自的汽车工厂类:

宝马工厂:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BaoMaFactory implements CarFactory {

    @Override
    public Car createCar() {
        System.out.println("宝马工厂生产汽车。");
        return new BaoMa();
    }

}

奔驰工厂:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BenChiFactory implements CarFactory {

    @Override
    public Car createCar() {
        System.out.println("奔驰工厂生产汽车。");
        return new BenChi();
    }

}

测试类:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class Test01 {

    @Test
    public void m1() {
        // 1. 先获取宝马车的工厂,如果想改奔驰的,仅改动一行代码即可。
        CarFactory carFactory = new BaoMaFactory();
        // 2. 利用工厂来制造汽车
        Car car = carFactory.createCar();
        car.running();
    }

}

工厂方法模式就很利于扩展,且不需要改动原来的代码,不管增加多少个品牌,只需要增加对应的工厂,以及实例就好了。

适用场景:

  1. 客户端不需要知道它所创建的对象的类。例子中我们不知道每个汽车具体叫什么名,只知道创建它的工厂名就完成了创建过程。
  2. 客户端可以通过子类来指定创建对应的对象。

AbstractFactory

抽象工厂的局限性比较大,并且它不符合OCP原则,工厂方法模式是创建一个对象,而抽象工厂它可以创建一组对象,这是和工厂方法模式最大的不同点。上述汽车的例子,假如汽车生产出来,出厂之前,我还需要给汽车做一个包装保养的服务,比如宝马有宝马的包装保养,奔驰有奔驰的包装保养,那是不是应该再创建一个专门做保养的工厂呢,肯定不是,抽象工厂的作用就是将汽车的生产、保养,以及后续的任务都做到一起,秉承一条龙服务,包括汽车的生产,包装,保养,维修等。

首先定义基本接口:

  • 汽车公共接口Car:
/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface Car {

    /**
     * car在跑。
     */
    void running();
    
}
  • 汽车维修服务接口CarFix:
/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface CarFix {

    /**
     * 汽车维修服务
     */
    void carFix(Car car);

}
  • 汽车包装服务接口CarPack:
/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface CarPack {

    /**
     * 汽车包装服务
     */
    void carPack(Car car);

}

三个接口的实现类:

  • Car类

宝马BaoMa:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BaoMa implements Car {

    @Override
    public void running() {
        System.out.println("宝马飞驰。");
    }

}

奔驰BenChi:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BenChi implements Car {

    @Override
    public void running() {
        System.out.println("奔驰奔跑。");
    }

}
  • 维修类CarFixService:
/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class CarFixService implements CarFix {

    @Override
    public void carFix(Car car) {
        System.out.println(car.getClass() + "在维修。");
    }

}
  • 包装类CarPackService:
/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class CarPackService implements CarPack {

    @Override
    public void carPack(Car car) {
        System.out.println(car.getClass() + "精美包装。");
    }

}

抽象工厂:

抽象工厂中提供了此工厂所有的服务以及功能,包括汽车生产、包装、维修等。

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public interface AbstractFactory {

    /**
     * 汽车创造
     */
    Car createCar();

    /**
     * 汽车修理服务
     */
    CarFix carFix(Car car);

    /**
     * 汽车包装服务
     */
    CarPack carPack(Car car);

}

具体的汽车工厂:

奔驰工厂BenChiFactory:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BenChiFactory implements AbstractFactory {

    @Override
    public Car createCar() {
        return new BenChi();
    }

    @Override
    public CarFix carFix(Car car) {
        return new CarFixService();
    }

    @Override
    public CarPack carPack(Car car) {
        return new CarPackService();
    }
}

宝马工厂BaoMaFactory:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class BaoMaFactory implements AbstractFactory {

    @Override
    public Car createCar() {
        return new BaoMa();
    }

    @Override
    public CarFix carFix(Car car) {
        return new CarFixService();
    }

    @Override
    public CarPack carPack(Car car) {
        return new CarPackService();
    }

}

测试类:

/**
 * Description:
 * @From www.zhangjianbing.com
 * @Author zhangjianbing
 */
public class Test01 {

    @Test
    public void m1() {
        // 1. 先按名字获取工厂
        AbstractFactory factory = new BenChiFactory();
        // 2. 生产车
        Car car = factory.createCar();
        // 3. 包装车
        CarPack carPack = factory.carPack(car);
        carPack.carPack(car);
        // 4. 上路
        car.running();
        // 5. 修理车
        CarFix carFix = factory.carFix(car);
        carFix.carFix(car);
        // -- 以上全部都是由工厂来完成。
    }

}

测试结果:

生产奔驰。
BenChi精美包装。
奔驰奔跑。
BenChi在维修。

抽象工厂适用场景:

  1. 和工厂方法一样客户端不需要知道它所创建的对象的类。
  2. 需要一组对象共同完成某种功能时。并且可能存在多组对象完成不同功能的情况。
  3. 系统结构稳定,不会频繁的增加对象。(因为一旦增加就需要修改原有代码,不符合开闭原则)

标签:www,zhangjianbing,Car,大话,Author,工厂,设计模式,public
来源: https://www.cnblogs.com/zhangjianbing/p/13654908.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有