标签:创建型 method lan factory 操作系统 不同类 ons 图片格式 现在
确保对象的唯一性。
使用一个私有构造函数、一个私有静态变量以及一个公有静态方法来实现。
public class LazySingleton {
private static LazySingleton instance;//私有静态变量
/**
* 私有构造器
*/
private LazySingleton(){}
/**
* 提供获取单例实例的静态方法
* 该方法可以保证线程安全,但在多线程高并发环境中系统性能低
* @return 单例实例对象
*/
synchronized public static LazySingleton getInstance(){
if (instance == null){
instance = new LazySingleton();
}
return instance;
}
}
该方法可以确保只实例化一个单例对象。但在多线程高并发环境中系统性能低,当第一个线程进入了getInstance()
方法后,其他线程只能等待。
public class DoubleCheckSingleton {
private static volatile DoubleCheckSingleton instance;
private DoubleCheckSingleton(){}
public static DoubleCheckSingleton getInstance(){
//第一重判断
if (instance == null){
//锁定代码块
synchronized (DoubleCheckSingleton.class){
//第二重判断
if (instance == null){
instance = new DoubleCheckSingleton();
}
}
}
return instance;
}
}
为什么需要判断两次呢?第一重判断是为了避免在高并发多线程环境中多线程等待造成的系统性能问题。第二重判断是为了确保只生成一个单例对象,倘若我们把第二重判断去掉,那么在某一时刻,A线程和B线程同时进入了第一重判断并且此时instance实例还没有生成,最终就会生成两个instance实例,所以两重判断一个都不能少。 双重检查锁方法,解决了线程安全的懒汉式生成单例对象的高并发系统性能问题。但是需要注意的是使用双重检查锁定来实现懒汉式单例类,需要在静态成员变量instance之前增加修饰符volatile,被volatile修饰的成员变量可以确保多个线程都能够正确处理,且该代码只能在JDK 1.5及以上版本中才能正确执行。由于volatile关键字会屏蔽Java虚拟机所做的一些代码优化,可能会导致系统运行效率降低,因此即使使用双重检查锁定来实现单例模式也不是一种完美的实现方式。
相关知识参考:Java并发编程:volatile关键字解析
/**
* Created by sunmood on 2018/12/14.
* 饿汉式单例
* 当类被加载时,静态变量instance会被初始化,
* 此时类的私有构造函数会被调用,单例类的唯一实例将被创建。
*/
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton(){}
public static EagerSingleton getInstance(){
return instance;
}
}
该方法是在类加载的时候就实例化一个单例对象,当线程调用时直接返回已经生成的实例。该方法没有延迟实例化带来的节约资源的好处。
/**
* Created by sunmood on 2018/12/15.
* 单例类中增加一个静态(static)内部类,
* 在该内部类中创建单例对象,
* 再将该单例对象通过getInstance()方法返回给外部使用
*/
public class IoDHSingleton {
private IoDHSingleton(){}
private static class HolderClass{
private static final IoDHSingleton instance = new IoDHSingleton();
}
public static IoDHSingleton getInstance(){
return HolderClass.instance;
}
public static void main(String[] args) {
IoDHSingleton s1,s2;
s1 = IoDHSingleton.getInstance();
s2 = IoDHSingleton.getInstance();
System.out.println(s1 == s2);
}
}
编译并运行上述代码,运行结果为:true,即创建的单例对象s1和s2为同一对象。由于静态单例对象没有作为Singleton的成员变量直接实例化,因此类加载时不会实例化Singleton,第一次调用getInstance()时将加载内部类HolderClass,在该内部类中定义了一个static类型的变量instance,此时会首先初始化这个成员变量,由Java虚拟机来保证其线程安全性,确保该成员变量只能初始化一次。由于getInstance()方法没有任何线程锁定,因此其性能不会造成任何影响。
使用原型实例指定要创建对象的类型,通过复制这个原型来创建新对象。
原型模式主要包含如下几个角色:
原型模式的核心在于如何实现克隆方法。
相关知识参考:浅克隆、深克隆、对象序列化、数据流
下面通过模拟一个简单的公文管理器来介绍原型管理器的设计与实现: Sunny软件公司在日常办公中有许多公文需要创建、递交和审批,例如《可行性分析报告》、《立项建议书》、《软件需求规格说明书》、《项目进展报告》等,为了提高工作效率,在OA系统中为各类公文均创建了模板,用户可以通过这些模板快速创建新的公文,这些公文模板需要统一进行管理,系统根据用户请求的不同生成不同的新公文。
其结构如图所示:
核心代码:
/**
* Created by sunmood on 2018/12/18.
* 抽象文档接口
*/
public interface OfficeDocument extends Cloneable {
OfficeDocument clone();
void display();
}
/**
* Created by sunmood on 2018/12/18.
* 可行性分析报告类
*/
public class FAR implements OfficeDocument {
public OfficeDocument clone() {
OfficeDocument far = null;
try {
far = (OfficeDocument) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("不支持复制!");
}
return far;
}
public void display() {
System.out.println("《可行性分析报告》");
}
}
/**
* Created by sunmood on 2018/12/18.
* 软件需求规格说明书
*/
public class SRS implements OfficeDocument {
public OfficeDocument clone() {
OfficeDocument srs = null;
try {
srs = (OfficeDocument) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("不支持复制!");
}
return srs;
}
public void display() {
System.out.println("《软件需求规格说明书》");
}
}
/**
* Created by sunmood on 2018/12/18.
* 原型管理器
* 使用饿汉式单例实现
*/
public class PrototypeManager {
private Hashtable hashtable = new Hashtable();
private static PrototypeManager prototypeManager = new PrototypeManager();
private PrototypeManager(){
hashtable.put("far",new FAR());
hashtable.put("srs",new SRS());
}
/**
* 增加新的公文对象
* @param key
* @param document
*/
public void addOfficeDocument(String key, OfficeDocument document){
hashtable.put(key,document);
}
/**
* 通过浅克隆获取新的对象
* @param key
* @return
*/
public OfficeDocument getOfficeDocument(String key){
return ((OfficeDocument) hashtable.get(key)).clone();
}
public static PrototypeManager getPrototypeManager(){
return prototypeManager;
}
}
客户端测试类:
public class Client {
public static void main(String[] args) {
//获取原型管理器对象
PrototypeManager pm = PrototypeManager.getPrototypeManager();
OfficeDocument doc1,doc2,doc3,doc4;
doc1 = pm.getOfficeDocument("far");
doc1.display();
doc2 = pm.getOfficeDocument("far");
doc2.display();
System.out.println(doc1 == doc2);
doc3 = pm.getOfficeDocument("srs");
doc3.display();
doc4 = pm.getOfficeDocument("srs");
doc4.display();
System.out.println(doc3 == doc4);
}
}
输出结果:
《可行性分析报告》 《可行性分析报告》 false 《软件需求规格说明书》 《软件需求规格说明书》 false
提供一个工厂方法,通过传入一个参数获取相应的对象实例,隐藏对象创建的内部细节。
简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
简单工厂模式主要包含如下几个角色:
Sunny软件公司欲基于Java语言开发一套图表库,该图表库可以为应用系统提供各种不同外观的图表,例如柱状图、饼状图、折线图等。Sunny软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。
结构设计如下图所示:
图形产品类核心代码:
/**
* Created by sunmood on 2018/12/13.
* 抽象图形类
*/
public interface Graphic {
/**
* 绘制图形
*/
void draw();
/**
* 擦除图形
*/
void erase();
}
/**
* Created by sunmood on 2018/12/13.
* 圆形类
*/
public class CircleGraphic implements Graphic {
public void draw() {
System.out.println("绘制圆形");
}
public void erase() {
System.out.println("擦除圆形");
}
}
/**
* Created by sunmood on 2018/12/13.
* 方形类
*/
public class RectangleGraphic implements Graphic {
public void draw() {
System.out.println("绘制方形");
}
public void erase() {
System.out.println("擦除方形");
}
}
/**
* Created by sunmood on 2018/12/13.
* 三角形类
*/
public class TriangleGraphic implements Graphic {
public void draw() {
System.out.println("绘制三角形");
}
public void erase() {
System.out.println("擦除三角形");
}
}
图形工厂类核心代码:
/**
* Created by sunmood on 2018/12/13.
* 图形工厂类
*/
public class GraphicFactory {
public static Graphic getGraphic(String type){
if (type.equalsIgnoreCase("circle")){
return new CircleGraphic();
} else if (type.equalsIgnoreCase("triangle")){
return new TriangleGraphic();
} else if (type.equalsIgnoreCase("rectangle")){
return new RectangleGraphic();
} else {
throw new UnSupportedShapeException("不支持的图形!");
}
}
}
测试方法:
@Test
public void testGetGraphic() throws Exception {
Graphic graphic = GraphicFactory.getGraphic("circle");
graphic.draw();
graphic.erase();
}
输出结果:
绘制圆形 擦除圆形
定义了一个创建对象实例的工厂方法接口,但由具体工厂子类决定要创建哪个对象实例。工厂方法模式把实例化推迟到子类。
工厂方法模式主要包含如下几个对象:
与简单工厂模式相比,工厂方法模式最重要的区别是引入了抽象工厂角色,抽象工厂可以是接口,也可以是抽象类或者具体类。具体产品由其对应的具体工厂负责生产。
使用工厂方法模式设计一个程序来读取各种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器,如GIF图片读取器用于读取GIF格式的图片、JPG图片读取器用于读取JPG格式的图片。
设计结构图如下所示:
产品类核心代码:
/**
* Created by sunmood on 2018/12/14.
* 图片读取器接口
*/
public interface PictureReader {
void read();
}
/**
* Created by sunmood on 2018/12/14.
*/
public class JPGReader implements PictureReader {
public void read() {
System.out.println("读取JPG图片。。。");
}
}
/**
* Created by sunmood on 2018/12/14.
*/
public class GIFReader implements PictureReader {
public void read() {
System.out.println("读取GIF图片。。。");
}
}
工厂类核心代码:
/**
* Created by sunmood on 2018/12/14.
* 工厂接口
*/
public abstract class PictureReaderFactory {
public void read(){
PictureReader reader = this.getPictureReader();
reader.read();
}
public abstract PictureReader getPictureReader();
}
/**
* Cre 大专栏 设计模式ated by sunmood on 2018/12/14.
*/
public class JPGReaderFactory extends PictureReaderFactory {
public PictureReader getPictureReader() {
return new JPGReader();
}
}
/**
* Created by sunmood on 2018/12/14.
*/
public class GIFReaderFactory extends PictureReaderFactory {
public PictureReader getPictureReader() {
return new GIFReader();
}
}
测试方法:
@Test
public void testGetPictureReader() throws Exception {
PictureReaderFactory factory = new GIFReaderFactory();
PictureReader reader = factory.getPictureReader();
reader.read();
}
输出结果:
读取GIF图片。。。
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。
抽象工厂模式主要包含如下几个角色:
Sunny软件公司欲推出一款新的手机游戏软件,该软件能够支持IOS和Android等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台。
软件结构设计如下图所示:
产品类核心代码:
/**
* Created by sunmood on 2018/12/14.
* 抽象游戏控制界面类
*/
public abstract class InterfaceController {
/**
* 界面显示方法
*/
public abstract void display();
}
/**
* Created by sunmood on 2018/12/14.
*/
public class AndroidInterfaceController extends InterfaceController {
public void display() {
System.out.println("安卓系统游戏界面。。。");
}
}
/**
* Created by sunmood on 2018/12/14.
*/
public class IOSInterfaceController extends InterfaceController {
public void display() {
System.out.println("IOS游戏界面。。。");
}
}
/**
* Created by sunmood on 2018/12/14.
* 抽象游戏操作控制类
*/
public abstract class OperationController {
/**
* 游戏控制器方法
*/
public abstract void operate();
}
/**
* Created by sunmood on 2018/12/14.
*/
public class AndroidOperationController extends OperationController {
public void operate() {
System.out.println("安卓系统游戏控制。。。");
}
}
/**
* Created by sunmood on 2018/12/14.
*/
public class IOSOperationController extends OperationController {
public void operate() {
System.out.println("IOS游戏控制。。。");
}
}
工厂类核心代码:
/**
* Created by sunmood on 2018/12/14.
* 游戏产品抽象工厂
*/
public abstract class GameFactory {
public abstract OperationController getOperationController();
public abstract InterfaceController getInterfaceController();
}
/**
* Created by sunmood on 2018/12/14.
* 安卓游戏工厂类
*/
public class AndroidGameFactory extends GameFactory {
public OperationController getOperationController() {
return new AndroidOperationController();
}
public InterfaceController getInterfaceController() {
return new AndroidInterfaceController();
}
}
/**
* Created by sunmood on 2018/12/14.
* IOS游戏工厂类
*/
public class IOSGameFactory extends GameFactory {
public OperationController getOperationController() {
return new IOSOperationController();
}
public InterfaceController getInterfaceController() {
return new IOSInterfaceController();
}
}
测试代码:
@Test
public void testGameFactory() throws Exception {
GameFactory gameFactory = new AndroidGameFactory();
InterfaceController interfaceController = gameFactory.getInterfaceController();
OperationController operationController = gameFactory.getOperationController();
interfaceController.display();
operationController.operate();
}
输出结果:
安卓系统游戏界面。。。 安卓系统游戏控制。。。
使用抽象工厂模式来设计,让我们可以在不修改原有代码的基础上添加新的产品族。比如,我们现在需要让该游戏支持Windows mobile系统,我们只需要新建Windows mobile的界面类、控制器类、具体工厂方法就可以对系统软件进行扩展,符合“开闭原则”。 但是,如果我们现在要增加一个产品等级,就需要修改原有代码,违背了“开闭原则”。 正因为抽象工厂模式存在“开闭原则”的倾斜性,它以一种倾斜的方式来满足“开闭原则”,为增加新产品族提供方便,但不能为增加新产品结构提供这样的方便,因此要求设计人员在设计之初就能够全面考虑,不会在设计完成之后向系统中增加新的产品等级结构,也不会删除已有的产品等级结构,否则将会导致系统出现较大的修改,为后续维护工作带来诸多麻烦。
复杂对象的组装与创建
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。
建造者模式主要包含如下几个角色:
Sunny软件公司欲开发一个视频播放软件,为了给用户使用提供方便,该播放软件提供多种界面显示模式,如完整模式、精简模式、记忆模式、网络模式等。在不同的显示模式下主界面的组成元素有所差异,如在完整模式下将显示菜单、播放列表、主窗口、控制条等,在精简模式下只显示主窗口和控制条,而在记忆模式下将显示主窗口、控制条、收藏列表等。
软件设计结构图如下所示:
播放软件产品类:
/**
* Created by sunmood on 2018/12/17.
* 播放器界面
*/
public class PlayerInterface {
private String menu;//菜单
private String playList;//播放列表
private String mainWindow;//主窗口
private String controlBar;//控制条
private String favoriteList;//收藏列表
@Override
public String toString() {
return "player.PlayerInterface{" +
"menu='" + menu + ''' +
", playList='" + playList + ''' +
", mainWindow='" + mainWindow + ''' +
", controlBar='" + controlBar + ''' +
", favoriteList='" + favoriteList + ''' +
'}';
}
//getter、setter方法。。。
}
建造者类
/**
* Created by sunmood on 2018/12/17.
* 播放器界面建造者抽象类
*/
public abstract class PlayerInterfaceBuilder {
protected PlayerInterface playerInterface = new PlayerInterface();
public abstract void buildMenu();
public abstract void buildPlayList();
public abstract void buildMainWindow();
public abstract void buildControlBar();
public abstract void buildFavoriteList();
//钩子方法
public boolean isBuildMenu(){
return true;
}
public boolean isBuildPlayList(){
return true;
}
public boolean isBuildFavoriteList(){
return true;
}
public PlayerInterface createPlayerInterface(){
return playerInterface;
}
}
/**
* Created by sunmood on 2018/12/17.
* 记忆模式建造者
*/
public class FavoritePatternBuilder extends PlayerInterfaceBuilder {
public void buildMenu() {
playerInterface.setMenu("菜单");
}
public void buildPlayList() {
playerInterface.setPlayList("播放列表");
}
public void buildMainWindow() {
playerInterface.setMainWindow("主窗口");
}
public void buildControlBar() {
playerInterface.setControlBar("控制条");
}
public void buildFavoriteList() {
playerInterface.setFavoriteList("收藏列表");
}
@Override
public boolean isBuildMenu() {
return false;
}
@Override
public boolean isBuildPlayList() {
return false;
}
@Override
public boolean isBuildFavoriteList() {
return super.isBuildFavoriteList();
}
}
/**
* Created by sunmood on 2018/12/17.
* 完整模式建造者
*/
public class FullPatternBuilder extends PlayerInterfaceBuilder {
public void buildMenu() {
playerInterface.setMenu("菜单");
}
public void buildPlayList() {
playerInterface.setPlayList("播放列表");
}
public void buildMainWindow() {
playerInterface.setMainWindow("主窗口");
}
public void buildControlBar() {
playerInterface.setControlBar("控制条");
}
public void buildFavoriteList() {
playerInterface.setFavoriteList("收藏列表");
}
}
/**
* Created by sunmood on 2018/12/17.
* 精简模式建造者
*/
public class SimplePatternBuilder extends PlayerInterfaceBuilder {
public void buildMenu() {
playerInterface.setMenu("菜单");
}
public void buildPlayList() {
playerInterface.setPlayList("播放列表");
}
public void buildMainWindow() {
playerInterface.setMainWindow("主窗口");
}
public void buildControlBar() {
playerInterface.setControlBar("控制条");
}
public void buildFavoriteList() {
playerInterface.setFavoriteList("收藏列表");
}
@Override
public boolean isBuildMenu() {
return false;
}
@Override
public boolean isBuildPlayList() {
return false;
}
@Override
public boolean isBuildFavoriteList() {
return false;
}
}
指挥者类:
/**
* Created by sunmood on 2018/12/17.
* 指挥者类
*/
public class PlayerInterfaceController {
public PlayerInterface construct(PlayerInterfaceBuilder playerInterfaceBuilder){
PlayerInterface playerInterface;
playerInterfaceBuilder.buildMainWindow();
playerInterfaceBuilder.buildControlBar();
if (playerInterfaceBuilder.isBuildFavoriteList()){
playerInterfaceBuilder.buildFavoriteList();
}
if (playerInterfaceBuilder.isBuildMenu()){
playerInterfaceBuilder.buildMenu();
}
if (playerInterfaceBuilder.isBuildPlayList()){
playerInterfaceBuilder.buildPlayList();
}
playerInterface = playerInterfaceBuilder.createPlayerInterface();
return playerInterface;
}
}
客户端测试类:
public class Client {
public static void main(String[] args) {
PlayerInterfaceController controller = new PlayerInterfaceController();
PlayerInterface playerInterface = controller.construct(new FavoritePatternBuilder());
System.out.println("记忆模式:" + playerInterface.toString());
playerInterface = controller.construct(new FullPatternBuilder());
System.out.println("完整模式:" + playerInterface.toString());
playerInterface = controller.construct(new SimplePatternBuilder());
System.out.println("精简模式:" + playerInterface.toString());
}
}
输出结果:
记忆模式:player.PlayerInterface{menu='null', playList='null', mainWindow='主窗口', controlBar='控制条', favoriteList='收藏列表'} 完整模式:player.PlayerInterface{menu='菜单', playList='播放列表', mainWindow='主窗口', controlBar='控制条', favoriteList='收藏列表'} 精简模式:player.PlayerInterface{menu='null', playList='null', mainWindow='主窗口', controlBar='控制条', favoriteList='null'}
建造者模式的核心在于如何一步步构建一个包含多个组成部件的完整对象,使用相同的构建过程构建不同的产品,在软件开发中,如果我们需要创建复杂对象并希望系统具备很好的灵活性和可扩展性可以考虑使用建造者模式。
标签:创建型 method lan factory 操作系统 不同类 ons 图片格式 现在
原文地址:https://www.cnblogs.com/wangziqiang123/p/11710994.html