首页 > 其他分享 >工厂模式总结——三个工厂

工厂模式总结——三个工厂

时间:2022-09-24 13:24:07浏览次数:64  
标签:总结 getInfo 模式 public Fruit 产品 工厂 class

在创建型模式中,工厂模式是我们日常使用最为频繁的设计模式之一。工厂模式可细分为简单工厂模式、工厂方法模式、抽象工厂模式。

简单工厂模式

模式简介

简单工厂模式:根据参数返回不同类的实例,这些类通常具有共同的父类。

简单工厂模式包括三个角色:

  1. 工厂 (Factory):用于创建所需产品,提供静态工厂方法,返回抽象产品类型 Product;
  2. 抽象产品 (Product):是工厂创建的所有对象的父类,封装了各种共有方法;
  3. 具体产品 (ConcreateProduct):工厂创建目标,继承抽象产品,实现了抽象产品的抽象方法。

应用实例

image-20220911203830271

  1. 工厂——FruitFactory

    public class FruitFactory {
    
        public static Object createFruit(String clazzName)  throws Exception{
            Object obj = null;
            if (clazzName.equals(Apple.class.getName())){
                obj = new Apple();
            } else if (clazzName.equals(Strawberry.class.getName())){
                obj = new Strawberry();
            } else if (clazzName.equals(Banana.class.getName())){
                obj = new Banana();
            } else {
                throw new ClassNotFoundException("没有找到该类");
            }
            return obj;
        }
    
        //升级简化版
        /*public static Object create(String clazzName) throws Exception{
            Object obj = null;
            Class clazz = Class.forName(clazzName);
            if (clazz.isAssignableFrom(Fruit.class)){
                obj = clazz.newInstance();
            } else {
                throw new ClassNotFoundException("没有找到该类");
            }
            return obj;
        }*/
    }
    
  2. 抽象产品——Fruit

    public abstract class Fruit {
        public abstract void getInfo();
    }
    
  3. 具体产品——Apple、Banana、Strawberry

    • Apple
    public class Apple extends Fruit{
        @Override
        public void getInfo() {
            System.out.println("这是一个砸中牛顿脑袋的苹果");
        }
    }
    
    • Banana
    public class Banana extends Fruit{
        @Override
        public void getInfo() {
            System.out.println("这是一根让犹太人致富的香蕉");
        }
    }
    
    • Strawberry
    public class Strawberry extends Fruit{
        @Override
        public void getInfo() {
            System.out.println("这是一颗甜到你心里的草莓");
        }
    }
    
  4. 客户端

    public class MainTest {
        public static void main(String[] args) throws Exception {
            //要个苹果
            Apple apple = (Apple) FruitFactory.createFruit(Apple.class.getName());
            apple.getInfo();
            //要颗草莓
            Strawberry strawberry = (Strawberry) FruitFactory.createFruit(Strawberry.class.getName());
            strawberry.getInfo();
            //要根香蕉
            Banana banana = (Banana) FruitFactory.createFruit(Banana.class.getName());
            banana.getInfo();
        }
    }
    

模式总结

优点:实现简单,屏蔽了对象创建过程,实现了对象创建和使用的分离。

缺点:集中了所有产品创建逻辑,职责过重;扩展困难,一旦添加类需修改源码;使用静态工厂方法,工厂角色无法形成继承结构。

使用场景:工厂负责创建对象较少。

工厂方法模式

模式简介

工厂方法模式:定义了一个用于创建对象的接口,但是让子类决定将哪个类实例化。工厂方法让一个类的实例化延迟到了子类。

工厂方法模式在简单工厂模式的基础上,引入了抽象工厂,将具体产品的创建延迟到了具体工厂,克服了简单工厂模式职责过重的缺点。

工厂方法模式包括了 4 个角色:

  1. 抽象工厂(AbstractFactory):定义了抽象工厂方法,用于返回一个产品,具体返回哪类产品由具体工厂决定。
  2. 抽象产品(AbstractProduct):是所有具体产品的公共父类,定义了产品的接口。
  3. 具体工厂(ConcreteFactory):是抽象工厂的子类,实现了抽象工厂的工厂方法,返回一个具体产品。
  4. 具体产品(ConcreteProduct):实现了抽象产品接口,由具体工厂创建。

应用实例

image-20220911203219104

  1. 抽象工厂——FruitFactory

    public abstract class FruitFactory {
        public abstract Fruit createFruit();
    }
    
  2. 抽象产品——Fruit

    public abstract class Fruit {
        public abstract void getInfo();
    }
    
  3. 具体工厂——AppleFactory、BananaFactory、StrawberryFactory

    • AppleFactory
    public class AppleFactory extends FruitFactory{
    
        @Override
        public Fruit createFruit() {
            return new Apple();
        }
    }
    
    • BananaFactory
    public class BananaFactory extends FruitFactory{
    
        @Override
        public Fruit createFruit() {
            return new Banana();
        }
    }
    
    • StrawberryFactory
    public class StrawberryFactory extends FruitFactory{
    
        @Override
        public Fruit createFruit() {
            return new Strawberry();
        }
    }
    
  4. 具体产品——Apple、Banana、Strawberry

    • Apple
    public class Apple extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一个砸中牛顿脑袋的苹果");
        }
    }
    
    • Banana
    public class Banana extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一根让犹太人致富的香蕉");
        }
    }
    
    • Strawberry
    public class Strawberry extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一颗甜到你心里的草莓");
        }
    }
    
  5. 客户端

    public class MainTest {
        public static void main(String[] args) throws Exception {
            FruitFactory factory = null;
            //要个苹果
            factory = new AppleFactory();
            Fruit apple = factory.createFruit();
            apple.getInfo();
            //要颗草莓
            factory = new StrawberryFactory();
            Fruit strawberry = factory.createFruit();
            strawberry.getInfo();
            //要根香蕉
            factory = new BananaFactory();
            Fruit banana = factory.createFruit();
            banana.getInfo();
        }
    }
    

模式总结

优点

  1. 隐藏了对象创建细节,用户创建对象时无需知道具体类名,只需知道相应的工厂类即可创建相应类对象。
  2. 在系统中添加新的产品时不会对现有代码产生影响,具有良好的扩展性,符合开闭原则。

缺点

  1. 每个产品需要添加对应的具体工厂类,类的数量因此成对增加,增加了系统复杂性和性能消耗。
  2. 引入了抽象层,增加了系统的抽象性和理解难度。

使用场景

  1. 客户端不需要知道它所需创建的类对象的类名;
  2. 抽象类通过子类来指定创建具体哪个类的对象。

抽象工厂模式

模式简介

抽象工厂:提供一个创建一系列相关或相关以来对象的接口,从而无需指定他们具体的类。

两个概念

产品等级结构:即产品的继承结构,水果是个抽象类,其子类包括苹果、香蕉、草莓,则抽象类与具体类之间构成了一个产品等级结构。

产品族:在抽象工厂模式中,产品族是同一个工厂生产的不同产品等级结构中的一组产品。例如当前有两个生产水果的工厂A和B都生产水果苹果、香蕉、草莓,则工厂A生产的苹果、香蕉、草莓构成一个产品族。

抽象工厂模式与工厂方法模式的区别在于,工厂方法模式针对的是一个产品等级结构,每一个具体工厂只能创建一个产品;而抽象工厂模式针对的是多个产品等级结构,其每个具体工厂负责创建一族的产品。

抽象工厂模式包括了 4 个角色:

  1. 抽象工厂(AbstractFactory):声明了一组用于创建一族产品的方法,每个方法对应一种产品。
  2. 抽象产品(AbstractProduct):为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  3. 具体工厂(ConcreteFactory):实现了抽象工厂中声明的创建产品的方法,生成了一组具体产品,这些具体产品构成了一个产品族,每个产品位于某个产品等级结构中。
  4. 具体产品(ConcreteProduct):实现了抽象产品接口,由具体工厂创建。

应用实例

image-20220911202602724

  1. 抽象工厂——FruitFactory

    public abstract class FruitFactory {
    
        public abstract Fruit createApple();
    
        public abstract Fruit createBanana();
    
        public abstract Fruit createStrawberry();
    
    }
    
  2. 抽象产品

    public abstract class Fruit {
        public abstract void getInfo();
    }
    
  3. 具体工厂——FruitFactoryA、FruitFactoryB

    • FruitFactoryA
    public class FruitFactoryA extends FruitFactory {
        
        @Override
        public Fruit createApple() {
            return new AppleA();
        }
    
        @Override
        public Fruit createBanana() {
            return new BananaA();
        }
    
        @Override
        public Fruit createStrawberry() {
            return new StrawberryA();
        }
    }
    
    • FruitFactoryB
    public class FruitFactoryB extends FruitFactory {
    
        @Override
        public Fruit createApple() {
            return new AppleB();
        }
    
        @Override
        public Fruit createBanana() {
            return new BananaB();
        }
    
        @Override
        public Fruit createStrawberry() {
            return new StrawberryB();
        }
    }
    
  4. 具体产品AppleA、AppleB、BananaA、BananaB、StrawberryA、StrawberryB

    • AppleA
    public class AppleA extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一个砸中牛顿脑袋的苹果,由工厂A生产");
        }
    }
    
    • AppleB
    public class AppleB extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一个砸中牛顿脑袋的苹果,由工厂B生产");
        }
    }
    
    • BananaA
    public class BananaA extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一根让犹太人致富的香蕉,由工厂A生产");
        }
    }
    
    • BananaB
    public class BananaB extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一根让犹太人致富的香蕉,由工厂B生产");
        }
    }
    
    • StrawberryA
    public class StrawberryA extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一颗甜到你心里的草莓,由工厂A生产");
        }
    }
    
    • StrawberryB
    public class StrawberryB extends Fruit {
        @Override
        public void getInfo() {
            System.out.println("这是一颗甜到你心里的草莓,由工厂B生产");
        }
    }
    
  5. 客户端

    public class MainTest {
        public static void main(String[] args) throws Exception {
            FruitFactory factoryA = new FruitFactoryA();
            FruitFactory factoryB = new FruitFactoryA();
            //要个苹果
            Fruit appleA = factoryA.createApple();
            appleA.getInfo();
            Fruit appleB = factoryB.createApple();
            appleB.getInfo();
            //要颗草莓
            Fruit strawberryA = factoryA.createStrawberry();
            strawberryA.getInfo();
            Fruit strawberryB = factoryA.createStrawberry();
            strawberryB.getInfo();
            //要根香蕉
            Fruit bananaA = factoryA.createStrawberry();
            bananaA.getInfo();
            Fruit bananaB = factoryA.createStrawberry();
            bananaB.getInfo();
        }
    }
    

模式总结

优点

  1. 隔离了具体类的生成,更换一个具体工厂就可以在某种程度上改变整个软件系统行为。
  2. 当一个产品族的多个对象被设计成一起工作时,能够保证客户始终只是用同一个产品族中的对象。
  3. 添加新的产品无需修改已有代码,符合开闭原则。

缺点

  1. 添加新的产品等级结构需要对原有系统进行较大修改,违背了开闭原则。

使用场景

  1. 系统有过个产品族,而每次使用只使用其中一个产品族;
  2. 产品等级结构稳定,设计完成后不会对系统增加或删除的产品等级结构。

工厂模式总结

  1. 简单工厂模式隐藏了对象创建细节,将象创建过程与系统业务分离,只需传入响应参数即可获得相应对象,缺点是职责过重。
  2. 工厂方法模式引入了抽象工厂,克服了简单工厂模式的缺点,将具体对象创建延迟到了子类且可以灵活扩展,但一定程度上造成了系统的类数量膨胀,损耗系统性能。
  3. 抽象工厂模式在工厂方法模式的基础上进一步扩展,每个具体工厂负责创建多个产品等级结构,减小了工厂方法模式造成的类膨胀问题,提供了系统效率。但是,抽象工厂模式存在开闭原则的倾向性,适用于只需扩展产品族,而产品登记结构稳定的系统。

标签:总结,getInfo,模式,public,Fruit,产品,工厂,class
From: https://www.cnblogs.com/xiaobaiLX/p/16725442.html

相关文章

  • 模板方法模式总结
    模板方法模式近期在探究Android源码时,发现Android里面用到了大量的钩子方法,下意识反应这是一种设计模式的应用——模板方法,于是重新翻阅了刘伟老师的《Java设计模式》......
  • 本周总结9.24
    这周确实是非常累的一周,基本一直在学习和配置Hbase相关的东西。初学大数据相关的东西最难的就是开始的配置环境了,由于对linux系统命令的不熟悉,配置就花费了3天的时间。我刚......
  • 吃透JAVA的Stream流操作,多年实践总结
    在JAVA中,涉及到对数组、Collection等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream的方式进行处理。例如,现在有这么一个需求:从给定句子......
  • java设计模式之七大原则
    java设计模式 以下内容为本人的学习笔记,如需要转载,请声明原文链接   https://www.cnblogs.com/lyh1024/p/16724932.html 设计模式1.设计模式的目的编写软件过......
  • 纯注解开发模式
    定义bean:   纯注解开发模式:用SpringConfig类来代替applicationContext.xml配置文件,利用注解@configuration代表了xml里的基本配置,在SpringConfig类中再加一个注解@......
  • 前端面试经常被问的题目,自己总结了一下
    JavaScript为什么要进行变量提升,它导致了什么问题?变量提升的表现是,无论在函数中何处位置声明的变量,好像都被提升到了函数的首部,可以在变量声明前访问到而不会报错。造成......
  • 总结一下最近前端面试被问到的题目吧
    浏览器乱码的原因是什么?如何解决?产生乱码的原因:网页源代码是gbk的编码,而内容中的中文字是utf-8编码的,这样浏览器打开即会出现html乱码,反之也会出现乱码;html网页编码是g......
  • 20220923测试总结
    P3216[HNOI2011]数学作业原题链接题目分析细心的话你是能够看出以下递推式的(我不够细心):\[F_n=F_{n-1}+10^k+n\]其中\(k=\lfloor\log_{10}n\rfloor\)硬性递推\(O(n^......
  • 代码随想录训练营|Day 4|202,19,面试题 02.07,142,总结
    24.SwapNodesinPairsGivena linkedlist,swapeverytwoadjacentnodesandreturnitshead.Youmustsolvetheproblemwithout modifyingthevaluesinth......
  • [原创] 关于模式识别模型有效性的验证——交叉验证Cross Validation
    作者:StevenYang([email protected])什么是交叉验证(CrossValidation)?比如有100条数据,一部分作为训练集,一部分作为测试集。用训练集(一般大于50%)进行训练,然后用......