【设计模式】2.工厂模式
创始人
2024-01-30 20:14:58
0

文章目录

  • 1. 工厂模式概述
  • 2. 简单工厂模式
  • 3. 工厂方法模式
  • 4. 抽象工厂模式

1. 工厂模式概述

工厂模式属于创建型模式的一种。

在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则

工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,使得如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦

开闭原则:

开闭原则要求对 扩展开放(对提供方),对修改关闭(对使用方)

工厂模式分为以下三种:

  • 简单工厂模式(不属于GOF的23种经典设计模式)
  • 工厂方法模式
  • 抽象工厂模式

2. 简单工厂模式

简单工厂不是一种设计模式,反而比较像是一种编程习惯

简单工厂模式的核心是定义一个创建对象的接口将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

实现简单工厂模式的基本思路是什么?

简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。简单工厂适用于需要创建的对象较少或客户端不关心对象的创建过程的情况

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VKO6QEBf-1668690825240)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.png)]

工厂类代码如下:

public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffee;}
}

咖啡店类

public class CoffeeStore {public Coffee orderCoffee(String type) {SimpleCoffeeFactory factory = new SimpleCoffeeFactory();//调用生产咖啡的方法Coffee coffee = factory.createCoffee(type);//加配料coffee.addMilk();coffee.addsugar();return coffee;}
}

测试类

public class Client {public static void main(String[] args) {//创建咖啡店类对象CoffeeStore store = new CoffeeStore();Coffee coffee = store.orderCoffee("latte");System.out.println(coffee.getName());}
}

工厂(factory)处理创建对象的细节,一旦有了SimpleCoffeeFactory,CoffeeStore类中的orderCoffee()就变成此对象的客户,后期如果需要Coffee对象直接从工厂中获取即可。这样也就解除了和Coffee实现类的耦合,同时又产生了新的耦合,CoffeeStore对象和SimpleCoffeeFactory工厂对象的耦合,工厂对象和商品对象的耦合。

后期如果再加新品种的咖啡,我们势必要需求修改SimpleCoffeeFactory的createCoffee方法的代码,违反了开闭原则。工厂类的客户端可能有很多,比如创建美团外卖等,这样只需要修改工厂类的代码,省去其他的修改操作。

简单工厂模式有什么优点?

简单工厂模式封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

简单工厂模式有什么缺点?

增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。

简单工厂模式还可以怎么实现?

简单工厂模式还可以使用静态工厂的方式实现,也就是将创建对象功能定义成静态的。

public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffe;}
}

3. 工厂方法模式

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B4Jo4q8C-1668690825241)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.png)]

工厂方法模式的主要角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

具体实现:

抽象工厂

public interface CoffeeFactory {Coffee createCoffee();
}

具体工厂

public class LatteCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new LatteCoffee();}
}public class AmericanCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new AmericanCoffee();}
}

咖啡店类

public class CoffeeStore {private CoffeeFactory factory;public CoffeeStore(CoffeeFactory factory) {this.factory = factory;}public Coffee orderCoffee(String type) {Coffee coffee = factory.createCoffee();coffee.addMilk();coffee.addsugar();return coffee;}
}

测试类

public class Client {public static void main(String[] args) {//创建咖啡店对象CoffeeStore store = new CoffeeStore();//创建对象//CoffeeFactory factory = new AmericanCoffeeFactory();CoffeeFactory factory = new LatteCoffeeFactory();store.setFactory(factory);//点咖啡Coffee coffee = store.orderCoffee();System.out.println(coffee.getName());}
}

由上面的代码可见,当我们需要添加产品的时候也需要添加相应的工厂类,但是却不用修改工厂类的代码,这样就解决了简单工厂模式的缺点。

工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

工厂方法模式有什么优点?

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

工厂方法模式有什么缺点?

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

4. 抽象工厂模式

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

image-20200401214509176

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式的主要角色如下:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8tYIWEU-1668690825242)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.png)]

抽象工厂

public interface DessertFactory {Coffee createCoffee();Dessert createDessert();
}

具体工厂

//美式甜点工厂
public class AmericanDessertFactory implements DessertFactory {public Coffee createCoffee() {return new AmericanCoffee();}public Dessert createDessert() {return new MatchaMousse();}
}
//意大利风味甜点工厂
public class ItalyDessertFactory implements DessertFactory {public Coffee createCoffee() {return new LatteCoffee();}public Dessert createDessert() {return new Tiramisu();}
}

测试类

public class Client {public static void main(String[] args) {//创建的是意大利风味甜品工厂对象//ItalyDessertFactory factory = new ItalyDessertFactory();AmericanDessertFactory factory = new AmericanDessertFactory();//获取拿铁咖啡和提拉米苏甜品Coffee coffee = factory.createCoffee();Dessert dessert = factory.createDessert();System.out.println(coffee.getName());dessert.show();}
}

抽象工厂模式有什么优点?

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

抽象工厂模式有什么缺点?

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

抽象工厂模式的应用场景有哪些?

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。

  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。

  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

抽象工厂模式与工厂方法模式的区别?

  1. 工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

  2. 抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例

请你比较以下简单工厂模式、工厂方法模式和抽象工厂模式的异同?

  • 简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
  • 工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。工厂方法的实现思路是,定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
  • 抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象。这是和工厂方法最大的不同点。抽象工厂的实现思路是,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

参考:

  • Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)_张维鹏的博客-CSDN博客
  • 【面试最常见的设计模式之工厂模式】_硕风和炜的博客-CSDN博客_工厂模式 面试
  • 黑马程序员Java设计模式详解, 23种Java设计模式(图解+框架源码分析+实战)

相关内容

热门资讯

欧洲最高火山时隔半年再次喷发   位于意大利西西里岛东岸的埃特纳火山于当地时间12月26日开始喷发。  12月27日的画面显示,火...
香港“兴”观察|创新赋能 提质...   茶餐厅老板投身“谷子经济”大受欢迎,钢铁公司用大数据传承焊接技艺,循环经济让零农药、零化肥蔬菜走...
铁路公安加强巡逻检查为多条新建...   近期,多条新建高铁陆续开通运营。各地铁路公安机关强化路地公安警务融合,加强与铁路企业协作,强化巡...
以“签证惩罚”相威胁 英国施压...   新华社北京12月28日电 英国内政部27日宣布,在英方威胁采取签证惩罚措施后,安哥拉和纳米比亚同...
新疆克孜勒苏州阿合奇县发生3....   央视网消息:据中国地震台网微信公众号消息,据中国地震台网正式测定,12月28日14时55分在新疆...
一组数据带你感受2025体育强...   记者近日从2025年全国体育局长会了解到,2025年我国运动员共在31个项目上获得146个世界冠...
只要在吃药,就千万别吃这种水果...   眼下,果香浓郁、口感清新的西柚正大量上市。但在这份美味背后,却隐藏着一个被许多人忽略的风险:在服...
民生一件事 | 从数天等待到立...   央视网消息:一般来说,居住证的申领从受理到制作发放需要几天到十几天的时间,辽宁日前实施居住证“立...
美国童星被刺身亡,曾出演《狮子...   中新网12月28日电 据美国有线电视新闻网(CNN)27日报道,曾在百老汇迪士尼音乐剧《狮子王》...
锚定育人根本 书写时代答卷(深...   2025年,是教育部党组确定的“实干年”。教育画卷,在时代浪潮中铺展。  立德树人事业汇聚更加广...