高级特性 三种工厂模式

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

是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

我们从一个实例展开

现在有一道面试题:使用java实现一个计算机控制台程序,要求输入数的运算,得到结果。

这道题目最原始的写法:

public class Computer {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入第一个数字");
float firstNum = in.nextFloat();
System.out.println("请输入第二个数字");

float secondNum = in.nextFloat();
System.out.println("请输入运算符");
String countQuato = in.next();
if("+".equals(countQuato)){
System.out.println("result:"+(firstNum+ secondNum) );

}else if("-".equals(countQuato));{
System.out.println("result:"+(firstNum- secondNum) );

}else if("*".equals(countQuato));{
System.out.println("result:"+(firstNum* secondNum) );

}else if("/".equals(countQuato));{
System.out.println("result:"+(firstNum/ secondNum) );

}
}

上面的写法实现虽然简单,但是却没有面向对象的特性,代码拓展性差,显然不是出题者想要考察的意图。

那么面向对象编程要如何在题中体现呢?

在面向对象编程语言中,一切都是对象,所以上面运算符号也应当作对象来处理。

public abstract class Operation {

public abstract float getResult(float firstNumber,float secondNumber);

}

我们首先建立一个抽象类

public class OperationFactory {

public static Operation getOperation(String quotaFlag){

Operation o = null;
switch (quotaFlag){
case "+": o =new AddOptation();
case "-": o =new SubOperationFactory();
case "*": o =new MulOperation();
case "/": o =new DivOperation();
default:break;

}
return o;
}

}

public class AddOPeration extends OPeration {

public float getResult(float firstNumber ,float secondNumber ){
return firstNumber+secondNumber;
}
}

public class SubOPeration extends OPeration {

public float getResult(float firstNumber ,float secondNumber ){
return firstNumber-secondNumber;
}
}

public class MulOPeration extends OPeration {

public float getResult(float firstNumber ,float secondNumber ){
return firstNumber*secondNumber;
}
}

public class DivOPeration extends OPeration {

public float getResult(float firstNumber ,float secondNumber ){
return firstNumber/secondNumber;
}
}

import java.util.Scanner;

public class Computer {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入第一个数字");
float firstNum = in.nextFloat();
System.out.println("请输入第二个数字");

float secondNum = in.nextFloat();
System.out.println("请输入运算符");
String countQuato = in.next();
if("+".equals(countQuato)){
System.out.println("result:"+(firstNum+ secondNum) );

}else if("-".equals(countQuato));{
System.out.println("result:"+(firstNum- secondNum) );

}else if("*".equals(countQuato));{
System.out.println("result:"+(firstNum* secondNum) );

}else if("/".equals(countQuato));{
System.out.println("result:"+(firstNum/ secondNum) );

}
}
private static float count(float firstNum,float secondNum,String countQuato){
//通过工厂类获取对象
Operation Operation =OperationFactory.getOperation(countQuota);
return operation.getResult(firstNum,secondNum);

}

}

}

简单工厂将对象的创建过程进行了封装,用户不需要知道具体的创建过程,只需要调用工厂类获取对象即可。

这种简单工厂的写法是通过switch-case来判断对象创建过程的。在实际使用过程中,违背了
开放-关闭原则,当然有些情况下可以通过反射调用来弥补这种不足。

简单工厂的优点/缺点: 

  • 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
  • 缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则

2   工厂方法 定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到了子类

工厂方法在简单工厂的基础上再包了一层工厂,所有的工厂都是此工厂的子类。而产生对象的类型由子类工厂决定。使用工厂方法来实现上面的加减乘除对象的创建

//定义上一级工厂店的接口
public interface IFractory {
public Operation generatOper();

}
//为每一个类创建工厂
/**
* 工厂方法 为每一个对象生成一个工厂类
*/
public class AddOperationFactory implements IFractory{
public Operation generatOper(){
return new AddOperation();
}
}public class SubOperationFactory implements IFractory{
public Operation generatOper(){
return new SubOperation();
}
}
public class MulOperationFactory implements IFractory{
public Operation generatOper(){
return new MulOperation();
}
}
public classDivOperationFactory implements IFractory{
public Operation generatOper(){
return new DivOperation();
}
}
//客户端代码
IFractory fractory =new AddOperationFactory();
Operation Operation = fractory .generatOper();
Operation.getResult(firstNum,secondNum);

 

工厂方法将类的实例化推迟到了其子类。所以使用工厂方法模式时,需要客户端决定实例化哪一个工厂类。选择判断问题还是存在的。也就是说,工厂方法把简单的工厂内部逻辑判断转移到了客户端来运行。你想要加的功能,本来是要改工厂类的,而现在是修改客户端。不过,我们在某些情况下通过工厂方法,只需要修改一行实例化的代码就可以实现系统元素的切换(比如切换数据源)。这也是很方便的。

工厂方法模式Factory Method,又称  多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

2.定义: 

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭
原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

3.延伸: 

在上面简单工厂的引入中,我们将实例化具体对象的工作全部交给了专门负责创建对象的工厂类(场务)中,这样就可以在我们得到导演的命令后创建对应的车(产品)类了。但是剧组的导演是性情比较古怪的,可能指令也是无限变化的。这样就有了新的问题,一旦导演发出的指令时我们没有预料到的,就必须得修改源代码。这也不是很合理的。工厂方法就是为了解决这类问题的。

工厂方法的优点/缺点: 

  • 优点:

    • 子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现。-- 加一层 间接性,增加了灵活性
    • 屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
    • 典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。
    • 多态性:客户代码可以做到与特定应用无关,适用于任何实体类。
  • 缺点:需要Creator和相应的子类作为factory method的载体,如果应用模型确实需要creator和子类存在,则很好;否则的话,需要增加一个类层次。(不过说这个缺点好像有点吹毛求疵了)

抽象工厂:

提供一个创建一系列相关相互依赖对象的接口,而无需指定他们具体的类。抽象工厂为不同产品族的对象创建提供接口。

使用场景:系统需要在不同产品族进行切换

代码实现:

import MulOperationFactory.IDepartment;

//不同产品组使用一个工厂
public class SalServerFactory implements IFacfory {
public IUser createUser(){
return new SqIServerUser();
}

}public IDepartment createDepartment(){

return new SqIServerDepartment();

}
public class AccessFactory implements IFacfory{
public IUser createUser(){
return new AccessUser();
public IDepartment createDepartment(){

return new AccessDepartment();

}

客户端:
IFacfory facfory = new AccessFactory();
IUser user = facfory. createUser();
IDepartment department = facfory. createDepartment();
user.insert();
user.getById();
department.insert();
department.getDepartmentById();

第一个抽象工厂最大的好处就是便于交换产品系列,具体工厂在代码中一般只出现一次。这就使得改变应用的具体工厂很容易。

第二个好处是他能让具体的创建对象实例和客户端分离,客户端是通过他们的抽象接口操作实例

抽象工厂不太易于拓展,如果需要自增功能,或者自增产品,则需要至少修改三个类,而且实例化的代码是写死在程序中的
, 这样无法避免违背开放-关闭原则。

对于上述问题,可以通过配置文件,结合反射的方式来解决。

  1. 3.   抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

 

抽象工厂:定义

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂的优点/缺点: 

  • 优点:

    • 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
    • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
    • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
  • 缺点:增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。(不过说这个缺点好像有点吹毛求疵了)

原文地址:https://www.cnblogs.com/xiaoxiao1016/p/9895414.html

时间: 2024-10-12 03:18:45

高级特性 三种工厂模式的相关文章

设计模式看书笔记(5) - 三种工厂模式比较

先看三种工厂模式部分主要代码(完整代码在前三篇博客): 简单工厂模式: public class SampleFactory { public static Animal createAnimal(String animalName){ if("Tiger".equals(animalName))){ return new Triger(); }else if("Dolphin".equals(animalName)){ return new Dolphin();

设计模式:三种工厂模式

三种工厂模式 简单工厂实现 简单工厂模式(严格来说这不算一种Gof的设计模式,更像是一种编程习惯)属于类的创建型模式,又叫做静态工厂方法模式.通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有相同的父类,应用继承将决定工厂的生产什么产品的决定权直接交到了客户手中,然后客户在输入自己的需求,得到最终的结果. 运用简单工厂模式实现生产pizza的业务场景. /// <summary> /// pizza创建工厂 /// </summary> public class Pi

C++ 三种工厂模式

工厂模式是将带有继承于基类的子类的创建过程交于一个工厂来创建,通过赋予不同的创建标识来创建不同的子类. 基于自己的理解和使用这里巩固一下工厂模式. 我们的项目目前使用最多的是简单工厂模式,不过其他两种模式:工厂模式和抽象工厂模式都是由简单工厂模式改进而来, 也很容易使用. 话不多说:见代码 一.简单工厂模式: 操作类: 接口类:CReadDocumentShowHandler,三个具体类:CReadWordShowHandler,CReadPdfShowHandler,CReadHtmlShow

三种工厂模式

一.简单工厂 对象的创建方式有很多,常用new来创建.但是这种做法在一些情况下,有很多不好的地方.比如创建操作散落在代码的多处.对象的创建职责和使用职责混合到一起等等.简单工厂可以一定程度上解决该问题.通常的做法是对被创建的多个类进行抽象,将公共成员和方法放到抽象类中.不同的类继承抽象类,对细节进行不同的实现.然后创建一个工厂类,将类实例化的操作封装到工厂类的静态工厂方法中,通过不同的参数来创建不同类的对象. 还有一种简化的做法是,将静态工厂方法放到实体类的公共抽象父类中. 优点: 对象的创建和

设计模式—三种工厂模式(JAVA)

一:简单工厂: 有一个实际工厂,这个工厂只能造一类的产品,这一类产品就是一个产品接口,会有多个具体产品实现这个接口,例 如,一个手机厂,生产苹果手机,三星手机: 缺点:在工厂类中集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中:对系统的维护和扩展不利: 使用场景:负责创建的对象比较少:客户只知道传入工厂类的参数,对于如何创建对象的逻辑不关心:容易违反高内聚责任分配原则,所以只在很简单的情况下应用: package com.designPattern.simp

java三种工厂模式

适用场合: 7.3 工厂模式的适用场合 创建新对象最简单的办法是使用new关键字和具体类.只有在某些场合下,创建和维护对象工厂所带来的额外复杂性才是物有所值.本节概括了这些场合. 7.3.1 动态实现 如果需要像前面自行车的例子一样,创建一些用不同方式实现同一接口的对象,那么可以使用一个工厂方法或简单工厂对象来简化选择实现的过程.这种选择可以是明确进行的也可以是隐含的.前者如自行车那个例子,顾客可以选择需要的自行车型号:而下一节所讲的XHR工厂那个例子则属于后者,该例中所返回的连接对象的类型取决

三种工厂模式(转)

资源:http://download.csdn.net/detail/zhangerqing/4835830 原文链接:http://blog.csdn.net/zhangerqing 工厂模式分为三种:普通工厂方法模式,静态工厂模式,抽象工厂模式: 11.普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图: 举例如下:(我们举一个发送邮件和短信的例子) 首先,创建二者的共同接口: [java] view plaincopy public interface

java 三种工厂模式

一.简单工厂模式 一个栗子: 我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类. public abstract class INoodles { /** * 描述每种面条啥样的 */ public abstract void desc(); } 先来一份兰州拉面(具体的产品类): public class LzNoodles extends INoodles { @Override public void desc() { System.out.println("兰州拉面 上海

深入理解Java的三种工厂模式

一.简单工厂模式 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现.被创建实例的类型可以是接口.抽象类,也可以是具体的类 实现汽车接口 1 public interface Car { 2 String getName(); 3 } 奔驰类 1 public class Benz implements Car { 2 @Override 3 public String getName() { 4 return "Benz"; 5 } 6 } 宝马类 1 public c