在说简单工厂模式之前,我们先来了解下活字印刷术。
古时候没有现在这么现代化,都是先刻好印版,然后用印版将文章去印在纸上。每写一篇,都得刻一版,好累。
毕昇,是个头脑很灵活的工匠,他就在想,如果我把每个字都单独刻出来,你用的时候自己去组合,这样不就省事了,因此,一项伟大的发明就出现了---活字印刷术。
活字印刷术有4大特点:
第一,要改文章的字,只需要替换对应的字模就行,这是可维护。
第二,每个字模可以多次使用,这是可复用。
第三,如果文章中用到的字没有,可以新刻一个对应的字,这是可扩展。
第四,如果想改变文章的排版,只需要改变字模的方向就行,灵活性好。
我们在开发中,经常遇到用户改需求的时候,你是否很累?我们用了这么多年面向对象编程语言,多态,继承等降低了程序之间的耦合,但是一种好的组织形式是必不可少的,让你有章可循,这就是我们的设计模式。
在设计过程中,我们要将业务逻辑和系统逻辑分离开来,这样就不会因为业务需求的变动,而各种痛苦不堪。
我们先来一例,了解下简单工厂模式。
一、简单工厂模式
现在有一个需求,让你设计一个计算器。你怎么做?
首先我们知道,计算器中包含最基本的加减乘除,参与运算的是两个数值,一个运算符,一个结果,如1+1=2。
很多人说这个很简单,然后将一堆代码写在一个方法中,各种条件判断。如果我后期要新增或者修改呢?比如我要新增一个开根运算,你怎么办?继续在原有客户端方法中新增分支?要是改错了怎么办?系统立马就不能用了。这种的就是典型的紧耦合,典型的面向对象过程编程,我们要像毕昇学习,用活字印刷版的思路去做。
大多数人,碰到问题就直觉的按照计算机能够理解的逻辑去做开发,而没有真正的做到面向对象。
面向对象编程的三大特性:继承,封装,多态。封装,大多数人都有意识,可是多态这个利器却没有用起来。
我们说过,类是具有一组相同行为和属性的对象的抽象,分类的目的是为了封装。但是如果涉及到的类的
具有相同的行为,只是实现不一样,那就使用接口。如果涉及到的类具有相同的属性和行为,只是行为的实现不一样,那么就使用继承。
根据多态的特性,利用父类可以去代表子类,对外,可以统一使用父类去做操作。这里,我们的计算器操作需要两个数,行为相同实现不一样,因此可以使用继承实现多态。这样,我们的类图就有了。
我们先创建这几个类:
package com.zhaodf.pattern.simpleFactory; public interface Operation { double getResult(); }
package com.zhaodf.pattern.simpleFactory; public class OperationAdd implements Operation{ private double numberA; private double numberB; public OperationAdd(double numberA,double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { return this.numberA+this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
package com.zhaodf.pattern.simpleFactory; public class OperationDiv implements Operation{ private double numberA; private double numberB; public OperationDiv(double numberA, double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { if(this.numberB==0){ System.out.println("除数不能为0"); return 0; } return this.numberA / this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
package com.zhaodf.pattern.simpleFactory; public class OperationMul implements Operation{ private double numberA; private double numberB; public OperationMul(double numberA, double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { return this.numberA * this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
package com.zhaodf.pattern.simpleFactory; public class OperationSub implements Operation{ private double numberA; private double numberB; public OperationSub(double numberA, double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { return this.numberA - this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
基本类创建完了,我们现在需要一个根据计算要求统一生产这些类的地方---工厂,并且,我们使用父类作为统一对外的窗口,使客户端调用过程透明。
我们的工厂类如下:
package com.zhaodf.pattern.simpleFactory; public class OperationFactory{ //我们用1-代表加法,2-代表减法,3-代表乘法,4-代表除法 public static Operation createOperation(double numberA,double numberB,int operationType){ Operation op = null; switch (operationType){ case 1: op = new OperationAdd(numberA,numberB); break; case 2: op = new OperationSub(numberA,numberB); break; case 3: op = new OperationMul(numberA,numberB); break; case 4: op = new OperationDiv(numberA,numberB); break; } return op; } }
客户端调用代码:
package com.zhaodf.pattern.simpleFactory; public class TestOperation { public static void main(String[] args){ double numberA = 1; double numberB = 2; Operation op = OperationFactory.createOperation(numberA,numberB,1); System.out.println(op.getResult()); } }
二、总结
简单工厂模式,将创建运算对象过程放在了工厂类中,并且使用面向对象编程的特性-多态,将运算对象的父类作为统一对外的窗口。这里也有个不好的地方,就是虽然简化了客户端的代码,但是工厂类中创建对象的分支也需要维护,后面我们讲到反射时,再来修改此处。
相关推荐
Java设计模式通常分为三类:创建型模式、结构型模式和行为型模式。 #### 1.1 创建型模式 创建型模式关注的是对象的创建机制,确保系统在合适的时间创建合适的对象。 ##### 1.1.1 工厂方法模式 **定义**:定义一...
Java设计模式是一种在特定场景下解决软件设计问题的方法论。设计模式能够帮助开发者以一种更加系统化、标准化的方式来构建软件系统,提高软件的可维护性和可扩展性。本文档通过图解和代码示例的方式详细介绍了23种...
### Java设计模式详解 #### 创建型模式 **1.1 工厂方法(Factory Method)** 工厂方法模式定义了一个创建对象的接口,但允许子类决定实例化哪一个类。这使得一个类的实例化可以被推迟到其子类。这种模式在以下...
Java设计模式-建造者模式详解 Java设计模式-建造者模式详解将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。生成器模式(Builder)是使用多个“小型”工厂来最终创建出一个完整对象。...
下面,我们将深入探讨几个重要的Java设计模式。 1. 单例模式:单例模式确保一个类只有一个实例,并提供全局访问点。在Java中,有多种实现单例的方法,如饿汉式(静态常量)、懒汉式(线程不安全)、双重检查锁定...
Java设计模式是软件开发中的一种最佳实践,它总结了在解决特定问题时程序员们经常采用的有效方法。这个“JAVA设计模式-chm版”资源显然包含了关于Java设计模式的详细信息,便于理解和应用。设计模式是对常见问题的...
Java设计模式详解合集是一份宝贵的资源,包含了丰富的面向对象设计原则和多种设计模式的深入讲解。这份资料旨在帮助开发者提升软件设计能力,遵循良好的编程实践,提高代码的可读性、可维护性和复用性。以下是其中...
在Java编程中,有23种经典的GoF(Gang of Four)设计模式,它们被分为三大类:创建型、结构型和行为型。本资源集合了这些模式的详细解释与源码分析,旨在帮助开发者深入理解和应用设计模式。 1. 创建型模式...
简单工厂、工厂方法和抽象工厂模式是其三种主要形式。 3. **抽象工厂模式**:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。 4. **建造者模式**:将复杂对象的构建与其表示分离,使同一种...
《Java设计模式PDF》是一本由James W. Cooper编写的经典书籍,该书详细介绍了Java编程语言中的设计模式,并通过实际案例深入探讨了这些模式的应用场景和实现细节。 在本书的前言部分(第3页),作者简要介绍了设计...
内容包括统一建模语言基础知识、面向对象设计原则、设计模式概述、简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式、适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、...
Java工厂模式是面向对象设计模式中的一个重要概念,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不直接实例化具体类,而是通过一个接口或者抽象类来间接创建。这种模式的核心在于将对象的创建过程...
Java设计模式主要包括创建型模式、结构型模式和行为型模式三大类。 #### 二、创建型模式 创建型模式关注的是对象的创建方式,通过不同的方式创建对象,可以更好地管理系统的复杂度,降低耦合度。 ##### 1.1.1 ...
### Java设计模式的应用 #### 一、引言 在当今快速发展的软件开发领域,Java作为一门功能强大且灵活的语言,不仅拥有丰富的API资源,还能与强大的数据库系统无缝对接。这使得许多开发人员能够以模块化的形式构建...
### Java设计模式详解 #### 1. 创建型模式 创建型模式主要关注的是对象的创建方式,它们提供了创建对象的最佳方法。以下是对几种常见的创建型模式的深入解析: ##### 1.1.1 工厂方法(Factory Method) **定义**...
JAVA 设计模式可以分为三种:创建模式、结构模式和行为模式。 1. 创建模式 创建模式是指在创建对象时使用的模式,包括 Factory(工厂模式)、Singleton(单例模式)、Builder(建造者模式)、Prototype(原型模式...
Java设计模式是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。 设计模式的六大原则 1. 开闭原则...