Java设计模式二
今天谈的是工厂模式,该模式用于封装和对对象的创建,万物皆对象,那么万物又是产品类,如一个水果厂生产三种水果罐头,我们就可以将这三种水果作为产品类,再定义一个接口用来设定对水果罐头的生成方法,在工厂类中定义一个方法可以根据我们提供给工厂的不同参数,来生成不同的产品。这样我们就可以方便后续的扩展,例如工厂又新生产另一种水果罐头,那么我们只需要添加相应的水果类,传入工厂相应的制造方法即可。下面我们通过具体的代码来理解工厂模式的实现。
标准的工厂类设计###
工厂类的定义是:定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使得一个类的实例化延迟到子类。我们定义一个水果类(抽象),让苹果,桔子类继承水果类。定义一个工厂(抽象),使用泛型的抽象方法,再定义一个或者多个具体的工厂继承该抽象工厂的抽象方法。生产中当调用工厂时传入想要生产的水果类(具体)即可。
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设计模式二的更多相关文章
- Java 设计模式(二)-六大原则
Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ...
- java设计模式(二)---工厂方法模式
2普通工厂方法模式 就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建. 2.1创建接口 /** * 发送接口 * Created by mrf on 2016/2/25. */ public ...
- java设计模式(二)
抽象工厂模式 对工厂同一抽象,便于扩展 interface Provider{ public Sender Send(); } class MailFactory implements Provide ...
- Java设计模式(十二) 策略模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...
- Java设计模式(二) 工厂方法模式
本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...
- Java设计模式(二)抽象工厂模式
一.场景描述 接<Java设计模式(一)工厂模式>https://www.cnblogs.com/mahongbiao/p/8618970.html 工厂模式有一缺点,就是破坏了类的封闭性 ...
- Java 设计模式系列(二十)状态模式
Java 设计模式系列(二十)状态模式 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改 ...
- Java 设计模式系列(十二)策略模式(Strategy)
Java 设计模式系列(十二)策略模式(Strategy) 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以 ...
- Java 设计模式系列(二二)责任链模式
Java 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...
随机推荐
- Java操作redis客户端Jedis连接集群(Cluster)
创建JedisCluster类连接redis集群. @Test public void testJedisCluster() throws Exception { //创建一连接,JedisClust ...
- 9.数据分组 group by
--数据分组 group by --作用:用于 对查询的数据进行分组,并处理 select deptno,job from emp group by deptno,job --1.分组之后,不能将除分 ...
- VSTO自动安装、卸载工具
使用本工具,不需要制作VSTO外接程序安装包,就可以把你的作品自动安装到其他电脑. 用法:下载VSTO_Setup.rar,解压缩,然后把你开发好的Debug文件夹和VSTO_Setup.exe一起发 ...
- linux下使用过的命令总结(未整理完)
1.常用命令不需解释 ls\cd\cp\mv\pwd\file\vi\vim\cat 2.getconf LONG_BIT 终端返回32表示操作系统32位,返回64表示操作系统64位. 3.ifcon ...
- cs231n spring 2017 lecture11 Detection and Segmentation
1. Semantic Segmentation 把每个像素分类到某个语义. 为了减少运算量,会先降采样再升采样.降采样一般用池化层,升采样有各种“Unpooling”.“Transpose Conv ...
- undefined reference to 问题汇总及解决方法 ----- 还有一种问题没有解决(可能是顺序问题)
1.链接时缺失了相关的目标文件 2.链接时缺少了相关的库文件 3.链接的库文件中有使用了另一个库文件 4.多个库文件链接顺序问题 5.定义与实现不一致 6.在c++代码中链接C语言的库 转载地址: ...
- $(document).ready()和window.onload方法
引用:http://www.jb51.net/article/21628.htm Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload ...
- Tmux 速成教程:技巧和调整
本文转自:http://blog.jobbole.com/87584/ 简介 有些开发者经常要使用终端控制台工作,导致最终打开了过多的标签页.如果你也是他们当中的一员,或者你正在实践结对编程,那么我推 ...
- json/xml processing model与xml和json的简要区别
1.JavaScript Object Notation(JSON) JSON是一种轻量级数据交换格式,广泛用作通用格式,用于序列化和反序列化通过Internet相互通信的应用程序中的数据.这些应用程 ...
- 导致提前layout的常见情况(通过chrome浏览器自带的控制台可以看到)
1.通过js获取DOM属性 2.增/删/DOM节点 3.改变浏览器窗口大小 4.改变字体 5.激活css伪类 6.修改DOM的属性,涉及到大小.位置等(该颜色不会激活提前的layout) 7.其他js ...