Java设计模式
前序:UML相关知识
1.类之间的关系
1.1 依赖
1.2 泛化关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OM6llikT-1625644992278)(assets/20210105183619419.png)]
1.3 实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-36c3dDLj-1625644992292)(assets/20210105184219412.png)]
1.4 关联
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nz9Qv4Bc-1625644992296)(assets/20210105183658839.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eGUMaKXj-1625644992298)(assets/20210105183757786.png)]
1.创建(对象)型设计模式:工厂设计模式, 抽象工厂设计模式,单例模式,建造者设计模式,原型设计模式
创建型设计模式:隐藏对象的创建过程。使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
2.结构型设计模式:
3.行为型设计模式:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-syinajlj-1625644992305)(assets/the-relationship-between-design-patterns.jpg)]
一 、 工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。在一些产品剧具有通用的方法时,可以通过工厂方法统一创建,可以很好的维护产品,当有时候需要修改产品的时候直接修改一处就好
1.1 简单工厂模式 (简单工厂不能称之为设计模式)
简单工厂模式是一个由工厂对象决定创建出哪一种产品类的实例,又叫静态工厂方法模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPBHWx85-1625644992311)(assets/5982616-c6198fc410af7f20.webp)]
-
Facotry: 工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
-
IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
-
Product:具体产品类,是简单工厂模式的创建目标。
这里我们用生产电脑来举例,假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑了,随着业务的拓展,这个代工生产商还要生产惠普和华硕的电脑,这样我们就需要用一个单独的类来专门生产电脑,这就用到了简单工厂模式。下面我们来实现简单工厂模式:
这里我们用生产电脑来举例,假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑了,随着业务的拓展,这个代工生产商还要生产惠普和华硕的电脑,这样我们就需要用一个单独的类来专门生产电脑,这就用到了简单工厂模式。下面我们来实现简单工厂模式:
第一步:创建抽象产品
public abstract class Computer {
/**
* 产品的抽象方法,由具体的产品类去实现
*/
public abstract void start();
}
第二步:具体产品
public class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("联想电脑启动");
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qELoqMxB-1625644992313)(assets/1617782539362.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q89bvrO7-1625644992316)(assets/1617782550303.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CvrUfzn2-1625644992317)(assets/1617782559661.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NYq5mlAV-1625644992317)(assets/1617782571528.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JFDqUBpk-1625644992318)(assets/1617782581732.png)]
1.2 工厂方法模式
在简单工厂中当我们需要添加新的产品时,需要再case中添加代码块,如何这个时候已经封装好了这个方法,那就没办法继续扩展。所以这里实现了工厂方法,一个抽象工厂一个具体工厂,一个抽象产品,一个具体产品。当内部无法修改的时候,把修改权限交给子类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o0BQwrlz-1625644992319)(assets/v2-05496005b1c28c14ab34df6b836c2494_hd.jpg)]
第一步:定义一个抽象产品类
abstract class Ball {
public Ball() {}
}
第二步:具体的产品类
class RedBall extends Ball {
public RedBall() {
System.out.println("生产红球");
}
}
class BlueBall extends Ball {
public BlueBall() {
System.out.println("生产蓝球");
}
}
第三步:工厂接口
interface BallFactory {
public Ball createBall();
}
第四步:具体工厂
class RedBallFactory implements BallFactory {
public RedBall createBall() {
return new RedBall();
}
}
class BlueBallFactory implements BallFactory {
public BlueBall createBall() {
return new BlueBall();
}
}
第五步:用户
class FactoryMethodUser {
public static void main(String[] args) {
// 工厂方法时代
RedBallFactory redBallFactory = new RedBallFactory();
RedBall redBall = redBallFactory.createBall();
BlueBallFactory blueBallFactory = new BlueBallFactory();
BlueBall blueBall = blueBallFactory.createBall();
}
}
工厂方法模式隐藏了类的创界结构而让工厂进行创建。
二、桥接设计模式
当出现两个维度的变化的时候就可以用桥接设计模式。比如形状和颜色,大小和味道。
抽象与实现部分分离,使他们都可以独立的变
通过组合来桥接其他的行为/维度
2.1 应用场景
- 系统需要在构建的抽象化角色和具体角色之间增加更多的灵活性
- 不想使用继承导致系统类的个数剧烈增加的系统
- 有时候一个类,可能拥有多个变化维度,比如啤酒,有不同的容量和品牌,可以使用继承组合的方式进行开发,加入维度很多,就容易出现膨胀,使用桥接模型就可以解决这个问题,且解耦
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TsXWVFbR-1625644992319)(assets/1624697316439.png)]
桥接:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pTDwlb19-1625644992320)(assets/1624697401549.png)]
2.2 实际操作
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:53
*/
public abstract class Phone
{
/**
* 桥接行为
*/
public Color color;
/**
* 自身方法
*/
public abstract void run();
public Phone(Color color)
{
this.color = color;
}
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:53
*/
public interface Color
{
void useColor();
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:54
*/
public class HuaWei extends Phone
{
public HuaWei(Color color)
{
super(color);
}
@Override
public void run()
{
this.color.useColor();
}
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:59
*/
public class SXPhone extends Phone
{
public SXPhone(Color color)
{
super(color);
}
@Override
public void run()
{
this.color.useColor();
}
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:58
*/
public class YellowColor implements Color
{
@Override
public void useColor()
{
System.out.println("黄色");
}
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 16:58
*/
public class BlueColor implements Color
{
@Override
public void useColor()
{
System.out.println("蓝色");
}
}
package bridge;
/**
* @author yemingheng
* @since 2021/6/26 17:02
*/
public class m
{
public static void main(String[] args)
{
HuaWei huaWei = new HuaWei(new RedColor());
huaWei.run();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cMI3vkBx-1625644992320)(assets/1624698903687.png)]
2.3 优缺点
- 优点
- 抽象和实现分离
- 优秀的扩展能力,符合开闭原则
- 缺点
- 增加系统的理解与设计难度
- 使用聚合关联关系建立在抽象层,需要更好的剥离业务
三、适配器设计模式(Adapter Pattern)
- 作为两个不兼容接口之间的桥梁,属于结构性设计模式
- 适配器模式是的原来有皆有不兼容不能工作的类可以一起工作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7QdE1WE-1625644992321)(assets/1624691028552.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NjfNLPQq-1625644992321)(assets/1624691246238.png)]
系统中的类不符合系统的需要
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nI8qMF4I-1625644992322)(assets/1624691410685.png)]
3.1 提升开发效率 接口适配器在日常开发里面的应用
- 接口适配器
有些接口中有许多抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为不是所有的方法都是我们需要的,有时值需要实现部分接口就可以了。
- 编码实战
package adapter;
/**
* @author yemingheng
* @since 2021/6/26 15:26
*/
public interface PayGateway
{
void unifiedOrder();
void refund();
void query();
void sendRedPacket();
}
package adapter;
/**
* @author yemingheng
* @since 2021/6/26 15:28
*/
public class PayGatewayAdapter implements PayGateway
{
@Override
public void unifiedOrder()
{
}
@Override
public void refund()
{
}
@Override
public void query()
{
}
@Override
public void sendRedPacket()
{
}
}
package adapter;
/**
* @author yemingheng
* @since 2021/6/26 15:29
*/
public class ProductVideoOrder extends PayGatewayAdapter
{
@Override
public void unifiedOrder()
{
super.unifiedOrder();
}
@Override
public void refund()
{
super.refund();
}
}
package adapter;
/**
* @author yemingheng
* @since 2021/6/26 15:30
*/
public class ProductVipVideoOrder extends PayGatewayAdapter
{
@Override
public void query()
{
super.query();
}
@Override
public void sendRedPacket()
{
super.sendRedPacket();
}
}
3.2 适配器实战,生成环境的接口需兼容新业务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MPFrAfaP-1625644992322)(assets/1624693504049.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P0KqJO32-1625644992323)(assets/1624693546779.png)]
3.3 适配器设计模式-类的适配器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBoKJ9BK-1625644992323)(assets/1624693700665.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eqO141Hc-1625644992324)(assets/1624693735092.png)]
public class OlderModule
{
public void methodA()
{
System.out.println("old MethodA ");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uHGzb1IZ-1625644992325)(assets/1624695588551.png)]
public interface TargetModule
{
void methodA();
void methodB();
void methodC();
}
public class AdapterModule extends OlderModule implements TargetModule
{
@Override
public void methodB()
{
}
@Override
public void methodC()
{
}
}