上一篇 | 下一篇 |
---|---|
Stream 深入,并行数据 | java并发编程 |
文章目录
前言
设计模式是前辈们总结出来的最佳实践,经过世间沉淀,形成的一套解决问题的方案。通常一个设计模式专注于解决一类问题。
学习设计模式有助于提高代码质量(重用代码、易阅读、易维护、可靠性、扩展性等方面),也有助于提升程序员的设计能力。本篇介绍几个常用的设计模式。
1、单例模式
常常会遇到唯一的现象,比如一个班级里班主任只有一个。
简单定义如下:
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
}
public class Classes {
public static void main(String[] args) {
// 创建班主任实例
ClassMaster classMaster = new ClassMaster();
// 创建班主任实例2
ClassMaster classMaster2 = new ClassMaster();
}
}
可以看到这样的话一个 class 里面会可能存在不止一个班主任。
要解决这个问题,就是要让 ClassMaster 类只有一个实例。
即单例模式就是:
让某个类只有一个实例
实现步骤:
1.1、将构造函数设为私有
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
private ClassMaster() {
}
}
这样外部就无法创建实例
1.2、在类中定义一个静态实例
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
private Static ClassMaster instance = new ClassMaster();
private ClassMaster() {
}
}
得保证有一个实例
因为静态属性是所有该类对象共有的,归属于整个类,所有这里可以理解为这个实例归属于这整个类,它并不能看成是某个对象的属性。
这就确保了一个类一个实例。
1.3、对外提供获取该静态实例的方法
因为这些属性都是私有的,所以得提供一个对外的接口来获取这个实例:
public class ClassMaster {
private String id;
// 班主任名称
private String name;
private String gender;
private Static ClassMaster instance = new ClassMaster();
private ClassMaster() {
}
public static ClassMaster getInstance(){
return instance;
}
}
至此,就完成了一个单例模式的封装。
2、简单工厂模式
先做个总结:简单工厂模式就是将服务拆分,当多个场所需要同一个服务时,就可以将此服务抽象出来,单独由某个工厂承担。
这样做的好处是,当这个服务需要改变时,原先是要在每个场所改动,现在只需要在工厂里改动即可。
实现步骤:
2.1、将同种产品类抽象出一个接口
java强调面向接口编程,就意味着工程应该生产一种产品,而不只是单个类的产品(这里的类指的是类和对象的类,一种产品里有多个类)。
比如水果:
水果接口:
public interface Fruit {
}
柠檬类:
public class Lemon implements Fruit {
}
西瓜类:
public class Watermelon implements Fruit {
}
榴莲类:
public class Durian implements Fruit {
}
2.2、将生产实例对象的过程收拢到工厂类中
public class FruitFactory {
public static Fruit getFruit(Customer customer) {
Fruit fruit = null;
if ("sweet".equals(customer.getFlavor())) {
fruit = new Watermelon();
} else if ("acid".equals(customer.getFlavor())) {
fruit = new Watermelon();
} else if ("smelly".equals(customer.getFlavor())) {
fruit = new Durian();
}
return fruit;
}
}
2.3、加上抽象类
通常某种产品会有属性,而接口中一般只提供方法(接口里的属性都是静态常量),要给该种产品添加属性的话,可以再加上个抽象类,然后抽象类是接口的实现类,由抽象类派生出各个产品类,则产品类也就是接口的实现类,并且拥有属性。
还是上面的例子:
水果接口:
public interface Fruit {
public String getName();
}
水果抽象类:
public abstract class AbstractFruit implements Fruit{
private String name;
public String getName(){
return name;
}
}
柠檬类:
public class Lemon implements Fruit {
}
西瓜类:
public class Watermelon implements Fruit {
}
榴莲类:
public class Durian implements Fruit {
}
这样一来,水果就都可以设置自己的name
属性,并且提供了getName()
接口。
3、抽象工厂模式
如果需要生产的不只是一种产品,而是多种产品、一系列,那简单工厂模式就有些吃力,或许你可以在简单工厂里多生产几种产品,但是这里有更优雅的解决方案:
抽象工厂:工厂的集合,工厂的工厂
实现步骤
以下图为例:
3.1、在简单工厂的基础上定义出工厂接口
public interface SnacksFactory {
// 取得水果
public Fruit getFruit(Customer customer);
// 取得饮料
public Drink getDrink(Customer customer);
}
其中水果工厂并不需要生产饮料,但它实现工厂接口后必须实现getDrink()
方法,返回null
即可
public class FruitFactory implements SnacksFactory {
public Fruit getFruit(Customer customer) {
Fruit fruit = null;
if ("sweet".equals(customer.getFlavor())) {
fruit = new Watermelon();
} else if ("acid".equals(customer.getFlavor())) {
fruit = new Lemon();
} else if ("smelly".equals(customer.getFlavor())) {
fruit = new Durian();
}
return fruit;
}
public Drink getDrink(Customer customer) {
return null;
}
}
3.2、将生产工厂实例对象的过程收拢到抽象工厂类中
public class SnacksFactoryBuilder {
public SnacksFactory buildFactory(String choice) {
if (choice.equalsIgnoreCase("fruit")) {
return new FruitFactory();
} else if (choice.equalsIgnoreCase("drink")) {
return new DrinkFactory();
}
return null;
}
}
3.3、也可加上抽象类
对于工厂,如果需要给工厂设置属性,也可定义一个工厂的抽象类,作为工厂接口的实现类;
对于产品,甚至可以定义一个AbstractSnake
抽象类,是Food
和Drink
接口的实现类,派生出所有产品类。
上一篇 | 下一篇 |
---|---|
Stream 深入,并行数据 | java并发编程 |