设计模式
创建型模式
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活
一、工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
📌在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
public interface Shape {
void draw();
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
public class ShapeFactory {
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
二、抽象工厂模式
说白了就是有个抽象工程,里面有调用获取某些工厂类的接口
三、单例模式
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
四、建造者模式,
如bulider、一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
五、原型模式
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
例如JAVA 中的 Object clone() 方法。
结构型模式
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
一、适配器模型
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
我们通过下面的实例来演示适配器模式的使用。其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。
二、桥接模式
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
我们通过下面的实例来演示桥接模式(Bridge Pattern)的用法。其中,可以使用相同的抽象类方法但是不同的桥接实现类,来画出不同颜色的圆。
三、过滤器模式
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
四、组合模式
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
我们通过下面的实例来演示组合模式的用法。实例演示了一个组织中员工的层次结构。
五、装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。
六、外观模式
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。
七、享元模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式。由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象。
八、代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
J2EE 模式
这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的
一、服务定位模式
当我们想要使用JNDI1查找定位各种服务时,使用服务定位器设计模式.考虑到为服务查找JNDI的高成本,Service Locator模式使用缓存技术.第一次需要服务时,Service Locator在JNDI中查找并缓存服务对象.通过Service Locator进行进一步查找或相同的服务在其缓存中完成,这在很大程度上提高了应用程序的性能.以下是此类设计模式的实体.
- 服务 - 实际服务将是处理请求.在JNDI服务器中查看此类服务的引用.
- 上下文/初始上下文 - JNDI上下文包含对服务的引用用于查找目的.
- 服务定位器 - 服务定位器是通过JNDI查找缓存服务来获取服务的单点联系人.
- 缓存 - 用于存储服务引用的缓存以重用它们
- 客户端 - 客户端是通过ServiceLocator调用服务的对象
📌通俗讲,即利用缓存,当用户访问某一服务时,先从缓存中检查是否有该服务对象,如果没有再重新创建该对象。
- 创建service接口
public interface Service {
void execute();
String getName();
}
- 创建实现类
实现Service1
public class Service1 implements Service {
public Service1() {
}
@Override
public void execute() {
log.info("执行" + name() + "方法");
}
@Override
public String getName() {
return "Service1";
}
}
实现Service2
public class Service2 implements Service {
public Service2() {
}
@Override
public void execute() {
log.info("执行" + name() + "方法");
}
@Override
public String getName() {
return "Service2";
}
}
- JNDI查找创建InitialContext
public class InitialContext {
public Service lookup(String jndiName) {
if (jndiName.equalsIgnoreCase("SERVICE1")) {
return new Service1();
} else if (jndiName.equalsIgnoreCase("SERVICE2")) {
return new Service2();
}
return null;
}
}
- 创建缓存类
public class Cache {
private final List<Service> services;
public Cache() {
services = new ArrayList<>();
}
public Service getService(String serviceName) {
return services.stream().filter(
i -> i.getName().equalsIgnoreCase(serviceName)
).findFirst().orElse(null);
}
public void addService(Service newService) {
if (newService != null && services.stream().noneMatch(
i -> i.getName().equalsIgnoreCase(newService.getName())
)) {
services.add(newService);
}
}
}
- 创建服务定位器
public class ServiceLocator {
private static final Cache cache;
static {
cache = new Cache();
}
public static Service getService(String jndiName) {
Service service = cache.getService(jndiName);
if (service == null){
InitialContext context = new InitialContext();
service = context.lookup(jndiName);
cache.addService(service);
}
return service;
}
}
- Test
ServiceLocator.getService("Service1").execute();
ServiceLocator.getService("Service2").execute();
- 借助spring进行代码简化
a. 增加工厂类,name对应component名称
public interface ServiceFactory {
Service getService(String name);
}
b. 对应的service实现类都加上Component注解
@Component("Service2")
public class Service2 implements Service
@Component("Service1")
public class Service1 implements Service
c. 增加配置类,调用spring的服务定位工厂类来获取对应service实现类
@Bean("serviceFactory")
public ServiceLocatorFactoryBean serviceLocator() {
ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
bean.setServiceLocatorInterface(ServiceFactory.class);
return bean;
}
d. 测试
@Resource(name = "serviceFactory")
private ServiceFactory serviceFactory;
@Test
void test(){
serviceFactory.getService("Service1").execute();
serviceFactory.getService("Service2").execute();
}
Java命名和目录接口(Java Naming and Directory Interface,JNDI)的简称 ↩︎
350



被折叠的 条评论
为什么被折叠?



