文档章节

设计模式基础

mysky221
 mysky221
发布于 2014/01/30 23:53
字数 1708
阅读 47
收藏 0

1.   简单工厂模式

(说明:本内容由网上视频教程整理,主要是方便自用,仅作参考。如果有错欢迎指出!)  

简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。







 

2.   工厂方法模式

简介:

和简单工厂模式差不多,都是“工厂模式”。

工厂方法模式同样属于类的创建型模式又被称为多态工厂模式工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

 

“开放和封闭原则”

开放:系统无限扩展;

封闭:不要修改既有代码。

 

简单工厂模式破坏了“开放和封闭原则”,比如,如果FruitFactory类是这样写:

public class FruitFactory {
    // 简单工厂,获取类实例的方法二:
// 这个方法的好处是参数名可以不分大小写(而且获取参数可以随便处理)
    // 缺点是增加水果的时候要增加if...else...不易扩展。
    public static FruitInter getFruit2(String type){
      
       if(type.equalsIgnoreCase("apple")){
           return new Apple();
//return Apple.class.newInstance()
       }else if(type.equalsIgnoreCase("banana")){
           return new Banana();
//return Banana.class.newInstance();
       }else{
           System.out.println("no such class!");
           return null; 
       }
}

 

那么,如果增加一个水果类(如Pear.java)的话,就需要增加一个else…的分支语句来处理,这就破坏了“开放和封闭原则”。

 

使用工厂方法模式:创建一个抽象工厂(或者说接口)FruitFactory.java,内部声明一个方法getFruit()方法;然后为每个水果类分别创建自己的工厂类,如AppleFactory.java,并实现FruitFactory接口,在实现的getFruit()方法中完成类的实例操作。

 

【具体做法:】

首先Apple.javaBanana.javaFruit.java三个类都和简单工厂类相同:

public interface Fruit {
    public void get();
}
 
public class Apple implements Fruit {
    public void get(){
       System.out.println("Collect apple.");
    }
}
 
public class Banana implements Fruit{
    public void get() {
       System.out.println("Collect banana.");
    }
}

 

其次,增加抽象工厂类(接口):

public interface FruitFactory {
    public Fruit getFruit();
}

 

然后,为Apple.javaBanana.jav a提供工厂类:

public class AppleFactory implements FruitFactory {
 
    public Fruit getFruit() {
       return new Apple();
    }
}
 
public class BananaFactory implements FruitFactory {
    public Fruit getFruit() {
       return new Banana();
    }
}

 

main方法中这么写:

public class MainClass {
    public static void main(String[] args) {
       // Apple
       FruitFactory fruitFactory1 = new AppleFactory();
       Fruit apple = fruitFactory1.getFruit();
       apple.get();
       // Banana
       FruitFactory fruitFactory2 = new BananaFactory();
       Fruit banana = fruitFactory2.getFruit();
       banana.get();
    }
}


3.   抽象工厂模式








4.   工厂模式在开发中的应用(计算器程序)

实现加减法!


**一般的思维

一般的思维是,直接在main方法中实现所有的业务,如下所示:


public class Main {

	public static void main(String[]args){
		
		System.out.println("---Caculation Program---");
		
		System.out.print("Input the first num: ");
		Scanner scanner = new Scanner(System.in);
		String num1 = scanner.nextLine();
		System.out.print("Input the operation: ");
		String oper = scanner.nextLine();
		System.out.println("Input the second num: ");
		String num2 = scanner.nextLine();
		
		double num1d = Double.parseDouble(num1);
		double num2d = Double.parseDouble(num2);
		double result = 0;
		
		if(oper.equals("+")){
			result = num1d + num2d;
		}else if(oper.equals("-")){
			result = num1d - num2d;
		}else{
			System.out.println("ERROR!");
			System.exit(0);
		}
		
		System.out.println("Result is: "+result);
		
	}
	
}

这样的代码冗余、可扩展性不好!
下面使用工厂模式实现。

**简单工厂模式实现

即使用专用的类(工厂类)来获取操作类(Operation类,用来实现各自的不同的四则运算



**工厂方法模式实现:

增加抽象工厂(接口):


5.   单例模式



(1)定义:

 

单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。

其实,GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

(2)为什么要有单例模式:

在应用系统开发中,我们常常有以下需求:

l  在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象;

l  在整个程序空间使用全局变量,共享资源;

l  大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。

 

因为Singleton模式可以保证为一个类只生成唯一的实例对象,所以这些情况,Singleton模式就派上用场了。

(3)单例模式的实现:

 饿汉式



像上面定义的类,外面的获取到的Person对象只会有一个。

懒汉式


 双重检查

在懒汉式中,我们将Synchronized加在了整个方法前,所以一个线程会守住整个方法,这样就影响了效率,我们是希望person只被实例化一次,可以将Synchronized加在实例化前:

这里还有个问题,就是当两个线程同时进入if的话,那么还会创建两个对象,下面加上两重循环:

    以上就是“双重检查”!

双重检查比懒汉式的效率更高:因为如果有多个线程同时执行的时候,不会让其他线程等待(仅第一次执行的时候可能会等待,以后都不会等待)!

对于饿汉式,饿汉式优点是简单且线程永远安全,但是比较耗费资源,因为只要类被加载就对象就被创建。

6.   原型模式

(1)定义:

Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。

 

(2)原理:

1)  由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身;

2)  目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值;

3)  根据对象克隆深度层次的不同,有浅度克隆深度克隆

4)  要想类能够被克隆,就必须让类实现Cloneable接口(其实仅仅是做一个声明而已!)。

 


假如,Person类里有属性:List<String>friends,即:

因为person1的属性friends持有的是另外一个对象的引用,所以在main方法中克隆的时候,(在栈中)person2克隆的也是一个引用,且指向同一个对象:

这就是“浅拷贝”,要想friends指向的也是全新的对象,那么就要手动添加(即“深拷贝”):

main方法:


© 著作权归作者所有

共有 人打赏支持
mysky221
粉丝 2
博文 65
码字总数 126905
作品 0
南京
私信 提问
(目录)设计模式(可复用面向对象软件的基础)

本系列“设计模式”博客使用Golang语言实现算法。所谓算法是指解决一个问题的步骤,个人觉得不在于语言。小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意。 本系列博客主要介绍...

chapin
2015/01/13
0
0
JAVA基础再回首(二十六)——面向对象思想设计原则、设计模式、简单工厂模式、工厂方法模式、单例设计模式之饿汉式和懒汉式、Runtime类

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m366917/article/details/52717096 JAVA基础再回首(二十六)——面向对象思想设计原则、设计模式、简单工厂模...

Aduroidpc
2016/10/01
0
0
Javascript设计模式与开发实践详见(一:单例模式)

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设...

littl_Prince
2016/04/05
0
0
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
11/06
0
0
javascript 设计模式之工厂(Factory)模式

工厂模式介绍 工厂模式是一个创建型的模式,主要就是创建对象。其中工厂模式又分为简单工厂模式和抽象工厂模式。简单工厂模式是通过工厂方法确定创建 对应类型的对象。抽象工厂模式是通过子类...

hlxiong
2014/04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

重磅!亚洲诚信实力斩获:“2018 DigiCert/Symantec 年度最佳创新合作伙伴”大奖

2018年11月13日-16日,全球顶级数字证书厂商,DigiCert/Symantec亚太区圆桌会议(Asia Partner Roundtable 2018)在日本大阪隆重召开。 亚洲诚信作为DigiCert/Symantec亚太区白金战略合作伙伴和...

亚洲诚信
20分钟前
2
0
始于阿里,回归社区:阿里8个项目进入CNCF云原生全景图

摘要: 一群技术理想主义者,与太平洋另一边的技术高手们正面PK,在这场躲不开的战役中,一起认真一把。 破土而出的生命力,源自理想主义者心底对技术的信念。 云原生技术正席卷全球,云原生...

阿里云官方博客
27分钟前
3
0
修改this指向(bind、call 和 apply)

一、bind bind 的其中一个用法就是:绑定函数,使其无论怎么样调用都用相同的 this 示例: var obj = { getThis: function() { console.log(this); }};obj.getThis()...

文文1
今天
1
0
WSL安装JDK8

下载地址 JDK_URL https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html UNLIMITED_STRENGTH_URL https://www.oracle.com/technetwork/java/javase/down......

terwergreen
今天
4
0
sparkStreaming基本概念

概述 Spark Streaming 是 Spark Core API 的扩展, 它支持弹性的, 高吞吐的, 容错的实时数据流的处理. 数据可以通过多种数据源获取, 例如 Kafka, Flume, Kinesis 以及 TCP sockets, 也可以通过...

freeli
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部