Java设计模式-工厂模式
Java设计模式-工厂模式4月打卡day29
关于作者
-
作者介绍
🍓 博客主页:
🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉🏆。
🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨💻。
什么是工厂模式?
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
简单编写一个类:
1、简单工厂模式
interface IFruit{
public void eat(); //吃水果
}
class Apple implements IFruit{
public void eat(){
System.out.println("削皮吃苹果!");
}
}
class Orange implements IFruit{
public void eat(){
System.out.println("剥皮吃橘子!");
}
}
public class Factory{
public static void main(String args[]){
IFruit fruit = new Apple();
//削皮吃苹果!
fruit.eat();
}
}
本程序非常简单就是通过接口的子类为接口对象实例化,但是本操作存在什么样的问题呢?
之前一直在强调,主方法或者是主类是一个客户端,客户端的操作应该越简单越好。但是在现在的程序之中,有一个最大的问题:客户端之中,一个接口和一个固定的子类绑在一起了。
在本程序之中,最大的问题在于耦合上,发现在主方法之中一个接口和一个子类紧密耦合在一起,这种方法比较直接,可以简单的理解为:A→B,但是这种紧密的方式不方便于维护,所以后来使用了A→B→C,中间经历了一个过渡,这样一来B去改变,C去改变,但是A不需要改变,就好比JAVA的JVM一样:程序→JVM→操作系统。
2、普通工厂模式
UML图:
源代码:
ProjectFactory.java
public interface ProjectFactory {
Project getname();
}
BlueFactory.java(ConcreteFactory1)
public class BlueFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new Bluepen();
}
}
RedFactory.java(ConcreteFactory2)
public class RedFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new redPen();
}
}
Project.java(产品类)
public interface Project {
void name();
}
Bluepen.java(ConcreteProject1)
public class Bluepen implements Project{
@Override
public void name() {
// TODO Auto-generated method stub
System.out.println("这是一个蓝色的笔");
}
}
RedFactory.java(ConcreteProject2)
public class RedFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new redPen();
}
}
测试类
public class Client {
public static void main(String[] args) {
Project pen = new RedFactory().getname();
pen.name();
Project pen1 = new BlueFactory().getname();
pen1.name();
}
}
运行结果:
这个时候发现客户端不在和一个具体的子类耦合在一起了,就算以后增加了新的子类,那么也只需要修改Factory类即可。
总结:
-
以后如果是自己编写的接口如果想要取得接口的 实例化对象,第一反应写工厂类
-
简单工厂和工厂方法模式的不同在于前者生成产生产品的行为封装在一个方法中,根据参数的类型进行实例化,同时不存在抽象接口。而后者则增加了抽象工厂,通过实现不同的工厂方法来创建不同的产品,一个方法通常对应一个产品,这种方式相较于前者扩展性更高,在需求增加时完全符合开闭原则和依赖倒置原则
使用场景:
消费者不关心它所要创建对象的类(产品类)的时候。
消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候。
例如:hibernate里通过sessionFactory创建session、通过代理方式生成ws客户端时,通过工厂构建报文中格式化数据的对象。
3、抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
抽象工厂模式与工厂方法模式的区别
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。.
如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。
UML图:
源代码:
Factory.java(抽象工厂)
public interface Factory {
PhoneProject projectPhone();
LaptopProject projectLaptop();
}
HuaWeiFactory.java(华为具体工厂)
public class HuaWeiFactory implements Factory{
@Override
public PhoneProject projectPhone() {
// TODO Auto-generated method stub
return new HuaWeiPhone();
}
@Override
public LaptopProject projectLaptop() {
// TODO Auto-generated method stub
return new HuaWeiLaptop();
}
}
XiaomiFactory.java(小米具体工厂)
public class XiaomiFactory implements Factory{
@Override
public PhoneProject projectPhone() {
// TODO Auto-generated method stub
return new XiaomiPhone();
}
@Override
public LaptopProject projectLaptop() {
// TODO Auto-generated method stub
return new XiaomiLaptop();
}
}
LaptopProject.java(笔记本产品)
public interface LaptopProject {
void getId();
void printInfo();
}
HuaWeiLaptop.java(华为笔记本)
public class HuaWeiLaptop implements LaptopProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号"+123);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产了华为电脑");
}
}
XiaomiLaptop.java(小米笔记本)
public class XiaomiLaptop implements LaptopProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号"+213);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产小米电脑");
}
}
PhoneProject.java(手机产品)
public interface PhoneProject {
void getId();
void printInfo();
}
HuaWeiPhone.java(华为手机)
public class HuaWeiPhone implements PhoneProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号:"+123412);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产华为手机");
}
}
XiaomiPhone.java(小米手机)
public class XiaomiPhone implements PhoneProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号:"+123412);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产了小米手机!!");
}
}
测试类:
public class Client {
public static void main(String[] args) {
PhoneProject huawei = new HuaWeiFactory().projectPhone();
huawei.printInfo();
huawei.getId();
PhoneProject xiaomi = new XiaomiFactory().projectPhone();
xiaomi.printInfo();
LaptopProject huawei1 = new HuaWeiFactory().projectLaptop();
huawei1.printInfo();
}
}
运行结果:
总结:
抽象工厂模式是工厂方法模式的升级版,后者面向单个产品,而前者面向的的是一个产品族。根据官方定义:为创建一组相关/互相依赖的对象提供一个接口而无需指定它们的具体类。 比如一个汽车工厂要生成骑车,而每种汽车都有车门、车轮胎等一系列产品,这意味着每增加一款汽车就需要增加一个新的工厂来提供新产品的实现。这时候就可以使用抽象工厂模式来进行设计。抽象工厂模式适用于一系列产品族。
优点:
-
抽象厂模式将产品族的依赖与约束关系放到抽象工厂中,便于管理。
-
职责解耦,用户不需要关心一堆自己不关心的细节,由抽象厂来负责组件的创建
-
切换产品族容易,只需要增加一个具体工厂实现,客户端选择另-个套餐就可以了
缺点:
-
抽象工厂模式类增加的速度很快,有一个产品族就需要增加一一个具体工厂实现,比较繁琐
-
产品族难以扩展产品。当产品族中增加一个产品时,抽象工厂接口中需要增加一个函数,对应的所有具体工厂 实现都需要修改,修改放大严重。
-
抽象厂并未完全屏蔽创建细节,给出的都是组件。对于这种情况可以结合工厂模式或简单工厂模式-起使 用。
使用场景:
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。大家应该已经发现了,其实抽象工厂模式如果只有一个组件的话,其实是退化到工厂方法模式,也就是没有了产品族的概念,只剩一一个产品了,因此简单工厂,厂方法,抽象工厂这三者之间是有内在联系的,区别只产品的复杂度。抽象工厂的本质是选择产品族,因此大家可以根据这个特征来识别是否可以应用抽象厂。
- 点赞
- 收藏
- 关注作者
评论(0)