设计模式之工厂模式与抽象工厂模式

工厂模式和抽象工厂模式

在设计模式里面,我们发现了其实工厂模式贺抽象工厂模式是单独分开的两个设计模式,接下来我们去探索一下他们呢得不同之处叭!

工厂模式的分类:

  • 简单工厂模式

    • 用来生产同一等级结构中得任意产品(对于增加新得产品,需要修改已有代码)
  • 工厂方法模式

    • 用来生产同一等级结构中得固定产品(支持增减任意产品)
  • 抽象工厂模式

    • 围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂得工厂

核心本质

  • 实例化对象不使用new,用工厂方法代替
  • 将选择实现类,创建对象同意管理和控制,从而将调用这跟我们得实现类解耦。

下面我们一起来做一个实例,看看三种模式怎么实现得叭。

简单工厂模式

百度百科:工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

结构图

image-20211113193244964

实现

Car接口

public interface Car {
    
    
    void name();
}

wuling类

public class WuLing implements Car{
    @Override
    public void name(){
        System.out.println("五菱神车");
    }
}

Tesla类

public class Tesls implements Car {
    
    
    @Override
    public void name(){
    
    
        System.out.println("特斯拉");
    }
}

工厂

/**
 * 静态工厂模式(简单工厂模式)
 * 添加一个新产品,如果你不修改原来的代码,做不到!**/
public class CarFactory {
    
    
    /**方法一*/
    public static Car getCar(String car){
    
    
        if(car.equals("五菱")){
    
    
            return new WuLing();
        }
        else if(car.equals("特斯拉")){
    
    
            return new Tesls();
        }
        else {
    
    
            return null;
        }
    }
    /**方法二*/
    public static Car getWuLing(){
    
    
        return new WuLing();
    }
    public static Car getTesls(){
    
    
        return new Tesls();
    }
}

实现类

public class Consumer {
    
    
    public static void main(String[] args) {
    
    
        /*需要知道接口,所有的实现类!工厂
        Car car1 = new WuLing();
        Car car2 = new Tesls();
        car1.name();
        car2.name();*/
        //需要五菱车
        Car car1 = CarFactory.getCar("五菱");
        //需要特斯拉
        Car car = CarFactory.getCar("特斯拉");
    }
}

分析一下这个代码:

我们这个代码确实比我们主类里面直接每次使用都要去创建一个新对象要好很多了,但是也伴随了其他的问题,比如,我们假如要添加新的车,我们必然要去修改原本的工厂类代码,这个可是大忌。

工厂方法模式

百度百科:工厂方法模式(FACTORY METHOD)是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品

结构图

image-20211113195206627

实现

由于之前的car接口和五菱还有特斯拉以及新加的mobai都差不多,所以接下来的代码仅展示一下他们的工厂类,可以参考自己写一下。

CarFactory接口(车厂)

public interface CarFactory {
    Car getCar();
}

对应车厂代表实现(WuLing车厂)

public class WuLingFactory implements CarFactory{
    
    
    @Override
    public Car getCar() {
    
    
        return new WuLing();
    }
}

实现类

public class Cunsumer {
    
    
    public static void main(String[] args) {
    
    
        Car car1 = new WuLingFactory().getCar();
        Car car2 = new TeslaFactory().getCar();
        Car car3 = new MobaiFactory().getCar();
        car1.name();
        car2.name();
        car3.name();
    }
}

因为工厂模式和抽象工厂模式设计模式是两种设计模式,所以在这里小结一下。

假如你已经自己测试过了,两种对比下来,在下面四种情况下对比结构复杂度、代码复杂度、编程复杂度、管理上的复杂度,都是简单工厂模式胜出,那为什么还要方法模式呢?因为他缺陷很明显,不符合OOP开闭原则。但在实际开发中,由以下两个建议

根据设计原则:工厂方法模式

根据实际业务:简单工厂模式

抽象工厂模式

百度百科:抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象

工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。

  • 定义

    • 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类
  • 使用场景

    • 客户端(应用层)不依赖于产品类实例如何呗创建、实现细节
    • 强调一系列相关的产品对象(属于同一产品簇)一起使用创建对象需要大量的重复代码
    • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现
  • 优点

    • 具体产品在应用层的代码隔离,无需关心创建的细节
    • 将一个系列的产品统一到一起创建
  • 缺点

    • 规定了所有可能呗创建的产品集合,产品簇中扩展新的产品困难
    • 增加了 系统的抽象性和理解难度
  • 它的UML图

image-20211113202148032

  • 产品族图

image-20211113202334259

  • 结构图

image-20211113202730477

  • 实现

因为类太多了,我类似的类就写一个,参考一下。

image-20211113203050154

  • 三个接口

手机接口

public interface IphoneProduct {
    
    
    /**开机*/
    void Start();
    /**关机*/
    void Shutdown();
    /**打电话*/
    void CallUp();
    /**发短信*/
    void sendSMS();
}

工厂接口

public interface IProductFactory {
    
    
    /**生产手机*/
    IphoneProduct iPHONEPRODUCT();
    /**生产路由器*/
    IRouterProduct rOUTERPRODUCT();
}

路由器接口

public interface IRouterProduct {
    
    
    /**开机*/
    void start();
    /**关机*/
    void ShutDown();
    /**开启wife*/
    void OpenWifi();
    /**设置路由器*/
    void Setting();
}

下面就以华为为例叭,毕竟我用的华为,哈哈哈!!!!

  • 华为产品

华为手机

public class HuaWeiPhone implements IphoneProduct{
    
    
    @Override
    public void Start() {
    
    
        System.out.println("华为开机");
    }
    @Override
    public void Shutdown() {
    
    
        System.out.println("华为关机");

    }
    @Override
    public void CallUp() {
    
    
        System.out.println("华为打电话");

    }
    @Override
    public void sendSMS() {
    
    
        System.out.println("华为发短信");

    }
}

华为路由器

public class HuaweiRouter implements IRouterProduct{
    
    
    @Override
    public void start() {
    
    
        System.out.println("启动华为路由器");
    }
    @Override
    public void ShutDown() {
    
    
        System.out.println("关闭华为路由器");
    }
    @Override
    public void OpenWifi() {
    
    
        System.out.println("打开华为路由器wifi");
    }
    @Override
    public void Setting() {
    
    
        System.out.println("华为路由器设置");
    }
}

华为工厂

public class huaweiFactory implements IProductFactory{
    
    
    @Override
    public IphoneProduct iPHONEPRODUCT() {
    
    
        return new HuaWeiPhone();
    }
    @Override
    public IRouterProduct rOUTERPRODUCT() {
    
    
        return new HuaweiRouter();
    }
}
  • 实现类
/**
 * @author:pier 2021/11/11
 **/
public class Client {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("============小米==========");
        //小米工厂
        xiaomiFactory xiaomiFactory = new xiaomiFactory();

        IphoneProduct iphoneProduct = xiaomiFactory.iPHONEPRODUCT();
        iphoneProduct.CallUp();
        iphoneProduct.sendSMS();

        IRouterProduct iRouterProduct = xiaomiFactory.rOUTERPRODUCT();
        iRouterProduct.OpenWifi();
        System.out.println("============华为==========");
        //华为工厂
        huaweiFactory huaweiFactory = new huaweiFactory();

        iphoneProduct = huaweiFactory.iPHONEPRODUCT();
        iphoneProduct.CallUp();
        iphoneProduct.sendSMS();

        iRouterProduct = huaweiFactory.rOUTERPRODUCT();
        iRouterProduct.OpenWifi();
    }
}

运行结果

image-20211113204023687

猜你喜欢

转载自blog.csdn.net/qq_43325476/article/details/121309802