软件设计模式的学习(以Java为例)

软件设计模式的学习(以Java为例)

一、任务要求

掌握“单例模型”和“工厂模式”(又分为简单工厂模型、工厂方法模型、抽象工厂模式)的概念和优缺点。调通例子代码。

二、任务过程

1.单例模式

(一)什么是单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

(二)单例模式的实现方法

常见的实现方式有:懒汉模式、饥汉模式、饱汉模式等方式实现,那我们我们紧接着就具体的一个一个的来看看他们的实现

懒汉模式

所谓懒汉模式,就是像一个懒汉一样,需要用到创建实例了程序再去创建实例,不需要创建实例程序就“懒得”去创建实例,这是一种时间换空间的做法,这体现了“懒汉的本性”。通过代码可以看出,懒汉单例模式在第一次调用 getInstance 方法时,实例化 LazySingleton 对象,在类加载时并不自行实例化,这种技术称为延迟加载技术(Lazy Load),即在需要的时候进行加载实例。
代码如下

    package com.design.singleton;
     
    /**
     * 懒汉单例模式,线程不安全
     */
    public class LazySingleton {
     
        private static LazySingleton lazySingleton = null;
     
        private LazySingleton(){
     
        }
     
        public static LazySingleton getInstance(){
            if (lazySingleton == null){
                lazySingleton = new LazySingleton();
            }
            return lazySingleton;
        }
    }
饥汉模式

所谓饥汉模式,个人理解就是一种程序设计实现的形象的说法,项目中经常有这样的场景:程序启动时,有很多耗时的操作,比如加载图片,加载文件等等,而友好的界面应该是让主界面加载进来,这些耗时费劲的操作放在后台的线程中去执行,完全不影响主界面的加载速度。所以软件设计人员就想到了在程序启动时将这些耗时的操作放在线程,故而把这种初始化加载的方式形象的比作:“饥汉模式”。
代码如下

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    cvIdentify::GetInstance();//饥汉模式初始化
    AutoTestUi w;
    w.show();
    return a.exec();
}
饱汉模式

不是线程安全的,因为是在需要的时候才会产生实例对象,生产之前会判断对象引用是否为空,这里,如果多个线程同时进入判断,就会生成多个实例对象,这是不符合单例的思想的。所以饱汉模式为了保证线程安全,就用synchronized关键字标识了方法。之所以被称为“饱汉”,因为它很饱,不急着生产实例,在需要的时候才会生产。
代码如下

public class SingletonPattern {//单例设计模式中的饱汉式
 private SingletonPattern(){}
 private static SingletonPattern instance=null;
 public static synchronized SingletonPattern getInstance() {
  if(instance==null){
   instance=new SingletonPattern();
  }
  return instance;
 }
}
双重锁模式

是饱汉模式的优化,进行双重判断,当已经创建过实例对象后就无需加锁,提高效率。也是一种推荐使用的方式。
代码如下

public class Singleton3 {
	private static Singleton3 singleton;
	
	private Singleton3(){
		
	}
	
	public static Singleton3 getInstance(){
		if(singleton == null){
			synchronized(Singleton3.class){
				if(singleton == null){
					singleton = new Singleton3();
				}
			}
		}
		return singleton;
	}
}
(三)单例模式优缺点
优点

实例控制:
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

灵活性:
因为类控制了实例化过程,所以类可以灵活更改实例化过程。

缺点

开销:
虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

可能的开发混淆:
使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

对象生存期:
不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

2.工厂模式

(一)什么是工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。

(二)工厂模式的实现方法
简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
结构图如下
在这里插入图片描述代码如下

public class SimpleFactoryPattern {
    public static void main(String[] args) {
        Product product = SimpleFactory.makeProduct(2);
        product.show();
    }
    //抽象产品
    public interface Product {
        void show();
    }
    //具体产品:ProductA
    static class ConcreteProduct1 implements Product {
        @Override
        public void show() {
            System.out.println("具体产品1显示...");
        }
    }
    //具体产品:ProductB
    static class ConcreteProduct2 implements Product {
        @Override
        public void show() {
            System.out.println("具体产品2显示...");
        }
    }
    //具体产品:ProductC
    static class ConcreteProduct3 implements Product {
        @Override
        public void show() {
            System.out.println("具体产品3显示...");
        }
    }
    final class Const {
        static final int PRODUCT_A = 0;
        static final int PRODUCT_B = 1;
        static final int PRODUCT_C = 2;
    }
    static class SimpleFactory {
        public static Product makeProduct(int kind) {
            switch (kind) {
                case Const.PRODUCT_A:
                    return new ConcreteProduct1();
                case Const.PRODUCT_B:
                    return new ConcreteProduct2();
                case Const.PRODUCT_C:
                    return new ConcreteProduct3();
            }
            return null;
        }
    }
}
工厂方法模式

工厂方法模式(FACTORY METHOD)是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品。
结构图如下
在这里插入图片描述代码如下

/**
 * @author hz
 * @version 1.0
 */
public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product a;
            AbstractFactory af;
            af = (AbstractFactory) ReadXML.getObject();
            //抽象工厂内容放入到外部配置文件xml/properties等文件中,通过I/O流加载从而创建出抽象工厂
            a = af.newProduct();
            a.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
//抽象产品:提供了产品的接口
interface Product {
    public void show();
}
//具体产品1:实现抽象产品中的抽象方法
class ConcreteProduct1 implements Product {
    public void show() {
        System.out.println("具体产品1显示...");
    }
}
//具体产品2:实现抽象产品中的抽象方法
class ConcreteProduct2 implements Product {
    public void show() {
        System.out.println("具体产品2显示...");
    }
}
//抽象工厂:提供了厂品的生成方法
interface AbstractFactory {
    public Product newProduct();
}
//具体工厂1:实现了厂品的生成方法
class ConcreteFactory1 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("具体工厂1生成-->具体产品1...");
        return new ConcreteProduct1();
    }
}
//具体工厂2:实现了厂品的生成方法
class ConcreteFactory2 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("具体工厂2生成-->具体产品2...");
        return new ConcreteProduct2();
    }
}
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
/**
 * @author hz
 * @version 1.0
 */
public class ReadXML {
    //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
    public static Object getObject() {
        try {
            //创建文档对象
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dFactory.newDocumentBuilder();
            Document doc;
            doc = builder.parse(new File("src/FactoryMethod/config1.xml"));
            //获取包含类名的文本节点
            NodeList nl = doc.getElementsByTagName("className");
            Node classNode = nl.item(0).getFirstChild();
            String cName = "FactoryMethod." + classNode.getNodeValue();
            //System.out.println("新类名:"+cName);
            //通过类名生成实例对象并将其返回
            Class<?> c = Class.forName(cName);
            Object obj = c.newInstance();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
结构图如下
在这里插入图片描述代码如下

//具体类的抽象接口
public interface Shape {
    //接口方法
}
//具体类Circle
public class Circle implements Shape {
    //接口方法实现
}
//具体类红色圆
public class RedCircle implements Shape {
    //接口方法实现
}
//...各种颜色的圆...
//具体类Triangle
public class Triangle implements Shape {
//接口方法实现
}
//具体类红色Triangle
public class RedTriangle implements Shape {
//接口方法实现
}
//...各种颜色的Triangle...
//工厂接口
public interface ShapeFactory {
    Shape getShape();
}
//CircleFactory
public class CircleFactory implements ShapeFactory {
    //返回实例
}
//RedCircleFactory
public class RedCircleFactory implements ShapeFactory {
    //返回实例
}
//...各种颜色的Circle的工厂...
//TriangleFactory 
public class TriangleFactory implements ShapeFactory {
    //返回实例
}
//RedTriangleFactory 
public class RedTriangleFactory implements ShapeFactory {
    //返回实例
}
//...各种颜色的Triangle的工厂...
(三)工厂模式的优缺点
优点

分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。

易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。

有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。

缺点

难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
上篇:软件设计模式例子代码  【例2.2】简单工厂方法模式-汽车保险  【例2.3】工厂方法模式-汽车保险  【例2.4】抽象工厂模式-房屋信息  【例2.5】生成器模式-房屋信息  【例2.6】单例模式-互联网连接  【例3.2】组合模式-五子棋代码  【例3.3】组合模式-空军指挥系统  【例3.4】组合模式-世界问候语  【例3.7】类适配器模式-客户信息验证  【例3.8】对象适配器模式-字符串排序  【例3.10】外观模式-安全系统  【例3.11】外观模式-椭圆功能  【例3.13】桥接模式-茶水机系统  【例3.14】桥接模式-几何立体体积  【例4.1】迭代器模式-矩阵搜索  【例4.2】迭代器模式-产品搜索  【例4.4】访问者模式-名牌鞋销售软件  【例4.5】访问者模式-计算机部件销售软件  【例4.6】命令模式-室内温度控制  【例4.7】命令模式-室内温度控制-2个GUI  【例4.8】命令模式-室内温度控制-3个GUI  【例4.10】中介者模式-旅游信息共享  【例4.11】中介者模式-海岛机场  【例4.13】策略模式-整数排序  【例4.14】策略模式-中国属相  【例4.16】状态模式-交通信号灯-设计1  【例4.16】状态模式-交通灯信号灯-设计2  【例4.16】状态模式-交通灯信号灯-设计3 下篇:软件体系结构例子代码  【例6.4】结构化设计-文件更新-C源代码  【例6.5】面向对象设计架构-文件更新  【例6.7】顺序批处理架构-文件更新  【例6.8】顺序批处理架构-图像处理  【例6.9】管道过滤器架构-主动过滤器  【例6.10】管道过滤器架构-被动过滤器  【例6.11】管道-过滤器架构-文件更新  【例6.12】管道-过滤器架构-图像处理程  【例6.14】事件体系结构-鼠标响应  【例6.17】事件体系结构-观察者模式-大草原1  【例6.18】事件体系结构-观察者模式-大草原2  【例6.19】事件体系结构-观察者模式-温度显示  【例6.21】层次架构-软件测试  【例6.22】层次架构-银行- Access数据库  【例6.23】MVC架构-二手车拍卖-无观察者  【例6.24】MVC架构-二手车拍卖-观察者-3个图形界面  【例6.25】MVC架构-二手车拍卖-观察者-1个图形界面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值