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 设计模式系列(二二)责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求 ...
随机推荐
- vue项目打包,生成dist文件夹,如何修改文件夹的名字
vue项目打包之后的dist文件目录是如下 如果想要修改dist或则static文件名称,需要打开config / index.js build: { // Template for index.ht ...
- hibernate中session.flush()
flush()session flush在commit之前默认都会执行, 也可以手动执行,他主要做了两件事: 1) 清理缓存. 2) 执行SQL. flush: Session 按照缓存中对象属性变化 ...
- 一个搜索框的小demo
一.实时按照输入的搜索值显示与其匹配的内容,隐藏其它内容 <%@ Page Language="C#" AutoEventWireup="true" Co ...
- B. Split a Number(字符串加法)
Dima worked all day and wrote down on a long paper strip his favorite number nn consisting of ll dig ...
- Forest Program(2019ccpc秦皇岛F)
题:http://acm.hdu.edu.cn/showproblem.php?pid=6736 题意:删掉一些边使得图不存在点双,求方案数. 分析:若一条边不属于点双,那么这条边有删和不删俩种选择, ...
- linux系统用户管理(一)
Linux系统用户管理1.用户管理*****2.Linux用户命令****3.用户创建的原理***4.密码管理***5.组命令管理**6.身份切换*****7.sudo提升权限***** 我们现在所使 ...
- iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码
iOS精选源码 对网络进行测速 自实现大标题,配合原生骨架屏demo 简单方便的pickerVIew记录数据 LZPickerView 科技风绘制组件,简单快速"画"出炫酷图案 R ...
- [LC] 127. Word Ladder
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...
- MOOC(14)- 从数据库中获取预期结果
数据库中的预期结果写的是SQL语句 从表格中读取到SQL语句,再去数据库获取真正的预期结果 # -*- coding: utf-8 -*- # @Time : 2020/2/18 9:50 # @Fi ...
- 微软要冷落windows是天方夜谭还是势在必行
自从90年代开始,微软就统治着PC桌面市场,真正意义上地改变了世界,在很长一段时间内,Windows就和阳光.空气.水.电能一样,成为生活必需品,无处不在,又让人感觉不到其存在,正因如此,微软的市值于 ...