今天谈的是工厂模式,该模式用于封装和对对象的创建,万物皆对象,那么万物又是产品类,如一个水果厂生产三种水果罐头,我们就可以将这三种水果作为产品类,再定义一个接口用来设定对水果罐头的生成方法,在工厂类中定义一个方法可以根据我们提供给工厂的不同参数,来生成不同的产品。这样我们就可以方便后续的扩展,例如工厂又新生产另一种水果罐头,那么我们只需要添加相应的水果类,传入工厂相应的制造方法即可。下面我们通过具体的代码来理解工厂模式的实现。

标准的工厂类设计###

工厂类的定义是:定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使得一个类的实例化延迟到子类。我们定义一个水果类(抽象),让苹果,桔子类继承水果类。定义一个工厂(抽象),使用泛型的抽象方法,再定义一个或者多个具体的工厂继承该抽象工厂的抽象方法。生产中当调用工厂时传入想要生产的水果类(具体)即可。

package com.factor;
/**
* 抽象水果类
*/
public abstract class Fruit {
public void getClassname(){
System.out.println("我属于水果");
}
public abstract void getname(); }
package com.factor;
/**
*
* @author Administrator
* 苹果
*/
public class Apple extends Fruit{ public void getname() {
// TODO Auto-generated method stub
System.out.println("我是一个苹果");
} }
package com.factor;
/**
*
* @author Administrator
* 桔子
*/
public class Orange extends Fruit{ public void getname() {
// TODO Auto-generated method stub
System.out.println("我是一个桔子"); } }
/**
*
* @author Administrator
* 抽象工厂
*/
public abstract class AbstractFactory {
public abstract <T extends Fruit> T createFriut(Class<T> c); }
/**
*
* @author Administrator
* 水果工厂
*/
public class FruitFactory extends AbstractFactory { @Override
public <T extends Fruit> T createFriut(Class<T> c) {
// TODO Auto-generated method stub
System.out.println("开始制作");
Fruit fruit=null;
try {
fruit = (Fruit)Class.forName(c.getName()).newInstance(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T)fruit; } }

场景类:

public class Click {

	/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub AbstractFactory factory = new FruitFactory();
Fruit apple = factory.createFriut(Apple.class);
apple.getClassname();
apple.getname(); } }

运行结果

工厂方法模式拥有良好的封装性,代码结构清晰,另外对对象的创建有约束的作用如上面代码中使用界定限制工厂只能生产水果),其次工厂模式的扩展性也很优秀,如需要增加产品的生产,只添加相应的产品类,适当的修改或者增加一个工厂类即可。我们从工厂方法中也能看到迪米特法则的运用,也就是高层模块只需要知道产品的抽象类,其它的类“不关心”。也可以看出一个产品只依赖产品的抽象这也是符合依赖倒置的。

工厂模式扩展###

1.缩小为简单工厂模式

如果我们只需要一个工厂生产水果,那么我们可以把工厂抽象类中的方法放到具体工厂类中即可。

/**
*
* @author Administrator
* 水果工厂
*/
public class FruitFactory { public static <T extends Fruit> T createFriut(Class<T> c) {
// TODO Auto-generated method stub
System.out.println("开始制作");
Fruit fruit=null;
try {
fruit = (Fruit)Class.forName(c.getName()).newInstance(); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T)fruit; } }

这使得我们的类变得简单,而且调用也简单了,所以称为简单工厂模式也叫做静态工厂模式。这样做也存在不符合开闭原则的缺点,不利于扩展。

2.多工厂模式

我们可以使用多个工厂来生产产品,比如有苹果工厂,有桔子工厂等。

/**
*
* @author Administrator
* 多工厂中的抽象工厂 区别: 不适用泛型 直接生成一个产品大类
*/
public abstract class MaxFaxtory {
public abstract Fruit create(); }

具体的工厂类:

/**
*
* @author Administrator
* 多工厂模式
*/
public class AppleFactory extends MaxFaxtory { @Override
public Fruit create() {
// TODO Auto-generated method stub
return new Apple();
}
/**
*
* @author Administrator
* 所工厂模式 桔子工厂
*/
public class OracleFactory extends MaxFaxtory{ @Override
public Fruit create() {
// TODO Auto-generated method stub
return new Orange();
} }

这样做使得各个工厂之间职责清晰,结构简单,但也是不利于扩展。我们可以使用一个协调类避免调用者与各个子工厂交流,协调类的作用是封装工厂类,对高层模块提供统一的访问接口。

3.替代单例模式

/**
*
* @author Administrator
* 单例类
*/
public class Singleton {
//不允许new
private Singleton(){ }
public void doSomething(){ } }
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class SingletonFactory {
private static Singleton singleton;
static{
try {
Class c1=Class.forName(Singleton.class.getName());
Constructor constructor=c1.getDeclaredConstructor();
constructor.setAccessible(true);
singleton = (Singleton)constructor.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

SingletonFactory通过反射的方法创建一个单例对象。

4.延迟初始化

一个对象被消费完毕后,并不立即释放,而是保持初始状态,等待再次被调用。


/**
*
* @author Administrator
* 延迟加载的工厂类
*/
public class ProductFactory {
private static final Map<String,Fruit> prMap = new HashMap();
public static synchronized Fruit createFruit(String type) throws Exception{
Fruit fruit = null;
if(prMap.containsKey(type)){
fruit = prMap.get(type); }else{
if(type.equals("apple")){
fruit = new Apple();
}else{
fruit = new Orange();
}
}
return fruit;
} }

延迟加载的框架易于扩展,可以通过判断Map中已有的对象数量来实现。通过延迟加载也降低了对象生成与销毁带来的问题。

Java设计模式二的更多相关文章

  1. Java 设计模式(二)-六大原则

    Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ...

  2. java设计模式(二)---工厂方法模式

    2普通工厂方法模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 2.1创建接口 /** * 发送接口 * Created by mrf on 2016/2/25. */ public ...

  3. java设计模式(二)

    抽象工厂模式 对工厂同一抽象,便于扩展 interface Provider{ public Sender Send(); } class MailFactory implements Provide ...

  4. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  5. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  6. Java设计模式(二)抽象工厂模式

    一.场景描述 接<Java设计模式(一)工厂模式>https://www.cnblogs.com/mahongbiao/p/8618970.html 工厂模式有一缺点,就是破坏了类的封闭性 ...

  7. Java 设计模式系列(二十)状态模式

    Java 设计模式系列(二十)状态模式 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改 ...

  8. Java 设计模式系列(十二)策略模式(Strategy)

    Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...

  9. Java 设计模式系列(二二)责任链模式

    Java 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...

随机推荐

  1. spi设备描述过程

    一.spi通信 中控制器驱动及spi设备.spi设备驱动的关系入下图: 控制器驱动以及设备全志已经完成,在/driver/spi/spi--sunxi.c  中,打开源码文件可以看到spi控制器属于平 ...

  2. javacv获取视频第一帧

    第一种是用ffmpeg工具,不过还得安装客户端软件,于是放弃了,还有一种是javacv开源工具,所以选择第二种: 第一种:ffmpeg工具 需要安装ffmpeg软件,支持windows和linux,视 ...

  3. 编译原理_P1004

    龙书相关知识点总结 //*************************引论***********************************// 1. 编译器(compiler):从一中语言( ...

  4. android物理动画、Kotlin客户端、架构组件、菜单效果、应用选择器等源码

    Android精选源码 Android一个有趣的Android动画交互设计 android可伸缩日历效果源码 关于界面,全新的卡片风格,支持夜晚模式 Android 用 Kotlin 实现的基于物理的 ...

  5. 记录ionic 最小化应用时所遇的问题

    ionic3与ionic4最小化插件安装不一样: ionic3安装方法: $ ionic cordova plugin add cordova-plugin-appminimize $ npm ins ...

  6. 关于Java集合框架总结

    Java集合专门用来存放多个对象,方便程序处理数据.Java提供了多种集合类,以便满足不同的应用需求,这些集合类分为两大系列:Collection和Map List List的通用方法 boolean ...

  7. 使用lambda表达式优雅你的事务代码

    我们在实现业务逻辑时,经常会有这种需求: 1.在当前事务A中开启新事务B,事务B中发生异常不可以回滚A,事务B成功执行后返回事务B的返回值: 2.在当前事务A中开启新事务B,事务B中发生异常要求回滚A ...

  8. yii执行流程简单介绍

    1. 用户访问 http://www.example.com/index.php?r=post/show&id=1,Web 服务器执行入口脚本 index.php 来处理该请求.  2. 入口 ...

  9. 吴裕雄--天生自然python学习笔记:python文档操作插入图片

    向 Word 文件中插入图片 向 Word 文件插入图片的语法为: 例如,在 cl ip graph.docx 文件的第 4 段插入 ce ll.jpg 图片,井将图片文件保存于 Word 文件内: ...

  10. [LC] 209. Minimum Size Subarray Sum

    Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...