设计模式分为三种类型,共23中设计模式
序列 | 模式&描述 | 包括 |
---|---|---|
1 | 创建型模式: 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 | 工厂模式、 抽象工厂模式、单例模式、建造者模式、原型模式 |
2 | 结构型模式: 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 | 适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式 |
3 | 行为型模式: 这些设计模式特别关注对象之间的通信 | 模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式 |
而常用到的七种主要有
创建型模式:单例模式、建造者模式、工厂模式、
结构型模式:适配器模式、代理模式
行为型模式:模板方法模式、策略模式
创建型模式
单例模式
注意:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
饿汉式
public class Singleton {
/**
* 未Lazy初始化
* 线程安全
* 优点:没有加锁,执行效率会提高。
* 缺点:类加载时就初始化,浪费内存。
*/
private Singleton() {}
private static final Singleton INSTANCE=new Singleton();
public static Singleton getSingleton() {
return INSTANCE;
}
}
懒汉式
public class Singleton {
/**
* Lazy初始化
* 线程安全
* 优点:第一次调用才初始化,避免内存浪费。
* 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
*/
private Singleton() {
}
private static Singleton instance;
public static synchronized Singleton getSingleton() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
双重锁
public class Singleton {
/**
* JDK1.5之后
* Lazy初始化
* 线程安全
* 采用双重锁机制,多线程安全的情况下保证性能
*/
private Singleton() {
}
private static Singleton instance;
public static synchronized Singleton getSingleton() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance== null)
instance=new Singleton();
}
}
return instance;
}
}
枚举
public enum Singleton {
/**
* JDK1.5之后
* 未Lazy初始化
* 线程安全
* 采用双重锁机制,多线程安全的情况下保证性能
*/
INSTANCE;
}
工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
public class Shape {
public static void main(String[] args) {
//使用该工厂,通过传递类型信息来获取实体类的对象。
ShapeFactory shapeFactory=new ShapeFactory();
//调用Rectangle的对象,并调用它的draw方法
Shape1 rectagle=shapeFactory.getShape("Rectangle");
rectagle.draw();
//调用Square的对象,并调用它的draw方法
Shape1 Square=shapeFactory.getShape("Square");
Square.draw();
//调用Circle的对象,并调用它的draw方法
Shape1 Circle=shapeFactory.getShape("Circle");
Circle.draw();
}
}
interface Shape1{
void draw();
}
class Rectangle implements Shape1{
@Override
public void draw() {
System.out.println("Rectangle method");
}
}
class Square implements Shape1{
@Override
public void draw() {
System.out.println("Square method");
}
}
class Circle implements Shape1{
@Override
public void draw() {
System.out.println("Circle method");
}
}
//创建一个工厂,生成基于给定信息的实体类的对象。
class ShapeFactory{
public Shape1 getShape(String shapeType) {
if(shapeType==null) {
return null;
}
if(shapeType.equalsIgnoreCase("Rectangle")) {
return new Rectangle();
}if(shapeType.equalsIgnoreCase("Square")) {
return new Square();
}if(shapeType.equalsIgnoreCase("Circle")) {
return new Circle();
}
return null;
}
}
建造者模式
参考:https://blog.csdn.net/zping0808/article/details/88926764
建造者设计模式是一个构造复杂对象的设计模式,在一个软件系统中,可能会面临创建一个复杂对象的工作,如果使用单一的方法或者单一的对象来创建会比较烦琐,当所创建复杂对象发生改变时,整个系统就可能面临剧烈的变化。这时就需要我们将这个复杂对象的创建过程分解成若干部分,各个子部分用一定的算法构成。但是,子部分可能会经常发生变化,如何能保证整体创建工作的稳定性呢?这就需要建造者模式,建造者模式把复杂对象的创建与表示分离,使得同样的构建过程可以创建不同的表示。
定义产品类型
//具体产品类
public class Product {
private String name;
private String desc;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getDesc() {return desc;}
public void setDesc(String desc) {this.desc = desc;}
@Override
public String toString() {
return "Product{" +"name='" + name + '\'' +", desc='" + desc + '\'' +'}';
}
}
定义抽象建造者
//定义抽象建造者
public abstract class Builder {
//设置产品名称
abstract void setName(String name);
//设置产品描述
abstract void setDesc(String desc);
//构建产品
abstract Product builderProduct();
}
定义具体建造者
//定义具体建造者
public class ConcreteProduct extends Builder {
private final Product product;
public ConcreteProduct() { product = new Product();}
@Override
void setName(String name) {
product.setName(name);
}
@Override
void setDesc(String desc) {
product.setDesc(desc);
}
@Override
Product builderProduct() {
return product;
}
}
定义指挥者类
//定义指挥者类
public class Director {
private final ConcreteProduct concreteProduct;
public Director() {
concreteProduct = new ConcreteProduct();
}
public Product getProduct(String name,String desc){
concreteProduct.setName(name);
concreteProduct.setDesc(desc);
return concreteProduct.builderProduct();
}
}
使用建造者模式
public static void main(String[] args) {
Director director = new Director();
Product product = director.getProduct("产品A", "A 的描述");
System.out.println(product);//Product{name='产品A', desc='A 的描述'}
}
结构型模式
适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
public class Dome {
public static void main(String[] args) {
Pattern1 pat=new PowerPattern();
pat.output();
}
}
//目标角色输出5V电压
interface Pattern1{
int output=5;
int output();
}
//适配角色 输入220V电压
class Pattern2{
private int input =220;
public int input() {
return input;
}
}
//适配器角色 充电器
class PowerPattern extends Pattern2 implements Pattern1{
@Override
public int output() {
int input=input();
System.out.println("适配之前电压"+input);
System.out.println("适配之后的电压"+output);
return input;
}
}
代理模式
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
public class Dome {
public static void main(String[] args) {
Image image=new ProxyImage();
image.display();
}
}
interface Image{
void display();
}
//目标类
class RealImage implements Image{
@Override
public void display() {
System.out.println("RealImage Display");
}
public void Disk() {
System.out.println("RealImage Disk");
}
}
//代理类,通过在类中实例一个目标类来调用
class ProxyImage implements Image{
private RealImage realImage;
@Override
public void display() {
System.out.println("ProxyImage Display");
if(realImage==null) {
realImage=new RealImage();
}
realImage.Disk();
}
}
行为型模式
模板方法模式
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
public class Dome {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
}
}
//创建一个抽象类,它的模板方法用final修饰
abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
// 模板
public final void play() {
// 初始化游戏
initialize();
// 开始游戏
startPlay();
// 结束游戏
endPlay();
}
}
//创建模板的扩展类
class Cricket extends Game {
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}
class Football extends Game {
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}
策略模式
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
public class Dome {
public static void main(String[] args) {
Strategy s=new OperationAdd();
System.out.println("10 + 5 = " + s.doOperation(5, 10));
s=new OperationSubstract();
System.out.println("10 - 5 = " + s.doOperation(10, 5));
s=new OperationMultiply();
System.out.println("10 * 5 = " + s.doOperation(5, 10));
}
}
interface Strategy {
public int doOperation(int num1, int num2);
}
class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
// TODO Auto-generated method stub
return num1+num2;
}
}
class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}