专业编程基础技术教程

网站首页 > 基础教程 正文

设计模式(一) 工厂模式

ccvgpt 2024-08-16 15:06:29 基础教程 112 ℃


简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

设计模式(一) 工厂模式

假如A类中创建了B类的对象,A类其实就对B类产生了依赖,如果后期B类因为需求的变更进行了改变,相应的对A类来说也要进行相应的变动,这一两个改动可能对程序影响还不是很大,但是当项目有许多对B类产生依赖的类,那这个改动就是巨大的,因此我们就可以考虑用一个单独的类来创造类实例的过程,这就是工厂,来,让我们看看具体简单工厂的实现案例:

现在有两个课程类型,一种是java,一种是python,我们需要根据不同条件拿到这两个课程,首先通过UML类图来了解大体框架


完成具体代码实现:

  • 创建抽象课程类AbClass
public abstract class AbClass { 
public abstract void sys(); 
}
  • java课程类
public class JavaClass extends AbClass{
 public void sys(){ System.out.println("我是java");
 }
 }
  • python课程类
public class PythonClass extends AbClass{
 public void sys(){ System.out.println("我是python"); 
} 
}
  • 简单工厂类
public class EasyFactory { 
public Object getType(String type)
 {
 switch (type){
 case "java": return new JavaClass(); 
case "python": return new PythonClass(); 
default: return null; } } }
  • 测试类
public class EasyFactoryTest { public static void main(String[] args) 
{
 EasyFactory easyFactory=new EasyFactory(); 
JavaClass java = (JavaClass) easyFactory.getType("java");
 java.sys(); 
PythonClass python = (PythonClass) easyFactory.getType("python"); 
python.sys(); } 
}

通过代码可知,通过工厂类EasyFactory来对创建逻辑进行处理,客户端只需要传相应的标识即可,这样就保证了客户端在调用时不需要再进行创建逻辑处理。缺点也很明显,倘若我们又增加了新的课程类,就要对创建逻辑进行更改,这不符合开放封闭原则,所以对于简单工厂模式来说,它适用于创建的对象较少,不会造成工厂类业务逻辑太复杂的情形。

工厂方法模式

简单工厂模式将实例创建工作交给工厂来实现,但增加课程类,就必须修改源代码,而工厂方法模式可以解决这个问题,在不改变原有代码的情况下对课程种类进行扩充。工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪个类,使一个类的实例化延迟到其子类。

现在我们用工厂方面模式来对简单工厂模式的实例进行改造

首先看下整个改造后的UML类图。


通过类图我们可以发现,相比于简单工厂模式,对工厂类进行了改造,创建了工厂接口类MethodFactory,然后又创建了PythonFactory,JavaFactory通过实现MenthodFactory来完成具体实例创建,这样当客户端要选择创建哪个课程类,只需选择相应的工厂类即可,具体代码实现如下:

 * 创建抽象课程类
public abstract class AbClass {
 public abstract void sys();
}
 * 创建具体课程java类
public class JavaClass extends AbClass {
 public void sys(){
 System.out.println("我是java");
 }
}
 * 创建具体课程Python类
public class PythonClass extends AbClass {
 public void sys(){
 System.out.println("我是python");
 }
}
 * 创建接口工厂类
public interface MethodFactory {
 public AbClass getType();
}
 * 创建具体java工厂类
public class JavaFactory implements MethodFactory {
 @Override
 public AbClass getType() {
 return new JavaClass();
 }
}
 * 创建具体python工厂类
public class PythonFactory implements MethodFactory {
 @Override
 public AbClass getType() {
 return new PythonClass();
 }
}
 * 创建测试类
public class MethodFactoryTest
{
 public static void main(String[] args) {
 MethodFactory methodFactory=new PythonFactory();
 AbClass type = methodFactory.getType();
 type.sys();
 }
}

相比于简单工厂模式,使用工厂方法模式可以不违背开放封闭原则,将选择实例化哪个课程类交给客户端进行处理,即使在后面新增课程类,也只需要扩展代码,不对原有代码进行改动。但工厂方法模式也有其缺陷,类的个数相对而言过多,增加了其复杂度,一般适用于创建对象需要大量重复代码或者客户端不需要知道具体实例如何被创建、实现等细节的场景。

抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类;抽象工厂模式可以为客户端提供一个接口,使客户端在不必指定产品的具体情况下创建多个产品族中的产品对象。

相对于工厂方法模式,如果需求进行变更,课程类除了有视频课程,还有书籍,视频课程和书籍属于同一个产品族,如果再按照工厂方法模式,不改变原有代码的情况下,基本上要对视频类的模式照搬创建相同数量的类才满足,这样就造成了大量的类出现,从而使项目变的更加复杂。

产品族是什么概念呢,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,例如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品结构中,海尔电视机、海尔电冰箱构成了一个产品族。

通过UML类图,首先我们创建了两个抽象类Book和Video,这两者属于一个产品族,然后创建具体的子类继承这两个类,而工厂类相对于工厂方法模式其实并没有新增新的工厂类,只是增加了一个创建实例的方法,具体代码如下:

//抽象课程视频类
public abstract class Video {
 public abstract void sys();
}
//抽象课程书籍类
public abstract class Book {
public abstract void readBook();
}
//java课程视频具体类
public class JavaVideo extends Video {
 @Override
 public void sys() {
 System.out.println("java视频");
 }
}
//python课程视频具体类
public class PythonVideo extends Video {
 @Override
 public void sys() {
 System.out.println("python视频");
 }
}
//java课程书籍类
public class JavaBook extends Book {
 @Override
 public void readBook() {
 System.out.println("java书籍");
 }
}
//python课程书籍类
public class PythonBook extends Book {
 @Override
 public void readBook() {
 System.out.println("python书籍");
 }
}
//课程工厂接口
public interface CourseFactory {
 public Video createVideo();
 public Book createBook();
}
//java课程工厂类
public class JavaFactory implements CourseFactory {
 @Override
 public Video createVideo() {
 return new JavaVideo();
 }
 @Override
 public Book createBook() {
 return new JavaBook();
 }
}
//python课程工厂类
public class PythonFactory implements CourseFactory {
 @Override
 public Video createVideo() {
 return new PythonVideo();
 }
 @Override
 public Book createBook() {
 return new PythonBook();
 }
}
//测试类
public class AbstractFactoryTest {
 public static void main(String[] args) {
 CourseFactory javaFactory=new JavaFactory();
 PythonFactory pythonFactory = new PythonFactory();
 Book pythonBook = pythonFactory.createBook();
 Book javaBook = javaFactory.createBook();
 Video javaVideo = javaFactory.createVideo();
 Video pythonVideo = pythonFactory.createVideo();
 pythonBook.readBook();
 pythonVideo.sys();
 javaBook.readBook();
 javaVideo.sys();
 }
}

抽象工厂模式的优点在于当一个产品族多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族的对象,并且增加新的产品族可以不用修改现有代码,但是当增加新的产品等级就需要修改现有的代码,所以它适用于产品等级变化不大,强调相关产品对象一起使用的场景。

最近发表
标签列表