当前位置: 首页 > article >正文

设计模式(主要的五种)

1.设计模式:

设计模式就是代码设计经验

2.设计模式的类型:

分为三大类:创建型模式,结构型模式,行为模式

创建型模式:

单例模式:某个类只能有一个实例,提供一个全局的访问点。

工厂模式:一个工厂类根据传入的参数决定创建出那一种产品类的实例。

抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。

原型模式:通过复制现有的实例来创建新的实例。

结构型模式

适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。

装饰模式:动态的给对象添加新的功能。

代理模式:为其他对象提供一个代理以便控制这个对象的访问。

亨元模式:通过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。

行为型模式

模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为。

观察者模式:对象间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对象交互。

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

3.单例模式:

1.一个类只有一个实例

2.只提供一个全局访问点

3.自我实例化( 一个对象在其自身的定义中创建自己的实例 )

懒汉模式在第一次调用时才创建实例,适合节省资源,但需要考虑线程安全问题。

饿汉模式在类加载时就创建实例,确保线程安全,但会占用更多资源,可能在不需要时也会初始化。

饿汉模式1:

很形象,通过getxxx静态方法把静态对象返回出去

这里的对象是私有的,防止外头的人修改,起到保护的作用

返回对象

public class UserMassage {
    //这是饿汉模式1

    //创建静态对象,自我实例化
    public static final UserMassage usermassage = new UserMassage();

    //提供全局访问点
    public  static UserMassage getUsermassage(){
        return  usermassage;
    }
    public void show(){
        System.out.println("我是单例模式");
    }

}

饿汉模式2:
public class UserMassage2 {
    //饿汉模式2
    public static final UserMassage2  usermassage;
    static {
        usermassage =  new UserMassage2();
    }
    public void show(){
        System.out.println("我是单例模式");
    }
}

懒汉模式:

先把静态对象设为null

判断静态对象是否为null

为null则生产一个返回

不为null则用这个对象

public class LayManModel {
    //懒汉模式

    //私有静态变量保存实例
    private static LayManModel layManModel;


    //提供公共的获取实例的方法
    public static LayManModel getInstance() {
        //使用synch保证线程安全
        if (layManModel == null) {
            synchronized (LayManModel.class) {
                if (layManModel == null) {
                    layManModel = new LayManModel();
                }
            }
        }

        return layManModel;
    }
        public void show () {
            System.out.println("我是懒汉模式");
        }

}

测试代码:

1.== 用来判断地址从而判断是否是同一个对象

2.通过全局访问点来创建对象

public class Main2 {
    public static void main(String[] args) {
        LayManModel layManModel1 = LayManModel.getLayManModel();
        LayManModel layManModel2 = LayManModel.getLayManModel();
        System.out.println(layManModel1 == layManModel2);
        layManModel1.show();
    }
}

优点:

在内存中只有一个实例,避免频繁的创建和销毁实例

缺点:

没有接口,不能继承

注意事项:getUserMassage() 方法中需要使用同步锁 synchronized (UserMassage.class) 防止多线程

同时进入造成 UserMassage被多次实例化

4.工厂模式:

优点

1、一个调用者想创建一个对象,只要知道其名称就可以了。

2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。

3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定

程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事 。

面条接口:
public interface MianTiao {
    //面条抽象类
    public abstract void des();


}
三种产品:三种面条

拉面:

public class LaMian implements MianTiao{
    @Override
    public void des() {
        System.out.println("我是拉面,兰州的拉面");
    }
}

泡面:

public class PaoMian implements MianTiao{
    @Override
    public void des() {
        System.out.println("我是泡面,大家都不爱吃的泡面");
    }
}

烩面:

public class HuiMian implements MianTiao{
    @Override
    public void des() {
        System.out.println("我是烩面,河南人爱吃的烩面");
    }
}

测试方法:
public class Main {
    //传入我要生产面
    public static void main(String[] args) {
        MianTiao miantiao = SimpleNoodlesFactory.createNoodles(LA_MIAN);
        miantiao.des();
    }
}

工厂:
public class SimpleNoodlesFactory {
   
    //简单面条工厂
    protected static final int PAO_MIAN = 1;
    protected static final int LA_MIAN = 2;

    protected static final int HUI_MIAN = 3;
    //这个方法是关键,用来生产的
    public static MianTiao createNoodles(int type) {
        switch (type) {
            case PAO_MIAN:
                return new PaoMian();
            case LA_MIAN:
                return  new LaMian();

            default:
                return new HuiMian();
        }
    }
}

抽象工厂:

因为工厂和工厂不一样,这个是面条工厂,我们随着企业的扩大需要包子工厂,生产工厂的工厂就是抽象工厂,也叫二级工厂。

5.装饰模式:

装饰模式是用来替代继承的一种设计模式。它通过一种无须定义子类的方式来给对象动态增加职责,使

用对象之间的关联关系取代类之间的继承关系。降低了系统的耦合,可以动态的增加或者删除对象的职 责

接口:

public interface Showable {
    //展示接口
    public abstract void show();
}

装饰器:

public abstract class Decorator implements Showable{
    Showable showable ;//持有一个善于展示自己某个家伙
    //抽象装饰器

    //构造函数
    public  Decorator(Showable showable){
        this.showable = showable;
    }
    //无需实现因为现在装饰器还不知道如何修饰
    public abstract  void show();
}

装饰对象:

public class Girl implements Showable{
    @Override
    public void show() {
        System.out.print("女友的素颜");
    }
}

装饰功能:

描眉:

public class MiaoMei extends Decorator{

    public MiaoMei(Showable showable) {
        super(showable);
    }

    //重写接口化妆后展示 描眉
    @Override
    public void show() {
        System.out.print("描眉(");
        showable.show();
        System.out.print(")");
    }
}

涂口红:

public class TuKouHong extends Decorator{
    public TuKouHong(Showable showable) {
        super(showable);
    }

    @Override
    public void show() {
        System.out.print("涂口红(");
        showable.show();
        System.out.print(")");

    }
}

测试方法:

这个装饰模式就是套的方式

和I/O流中的创建可像

public class Main {
    public static void main(String[] args) {
        //创建女友对象
        Girl girl = new Girl();
        //将女友放入描眉类
        MiaoMei lyw = new MiaoMei(girl);
        TuKouHong cmy = new TuKouHong(lyw);
        cmy.show();
    }
}

6.代理模式:

代理模式 指由一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其他相关 业务的处理。

/*
* 定义Network接口
*/
public interface Network {
public void browse(); // 定义浏览的抽象方法
}
/*
* 真实的上网操作
*/
public class Real implements Network {
//重写抽象方法
public void browse() {
System.out.println("上网浏览信息!");
}
}
/*
* 代理上网
*/
public class Proxy implements Network {
private Network network;
// 设置代理的真实操作
public Proxy(Network network) {
this.network = network; // 设置代理的子类
}
// 身份验证操作 其他操作
public void check() {
System.out.println("检查用户是否合法!");
}
//代码实现上网
public void browse() {
this.check(); // 调用具体的代理业务操作
this.network.browse(); // 调用真实的上网操作
}
}
public static void main(String args[]) {
Network net = null; // 定义接口对象
net = new Proxy(new Real()); // 实例化代理,同时传入代理的真实操作
net.browse(); // 调用代理的上网操作
}

7.观察者模式

就是举个例子:订报纸

报纸厂家和订阅报纸的人之间这种一对多的就可以称为观察者模式

报纸厂家是被观察者

订阅报纸的人是观察者

当你订阅了 一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社 和订报纸的客户就是上面文章开头所说的“一对多”的依赖关系

奶厂:

接口:

public interface Subject {
  

    //订阅
    void attach(Observer observer);
    //取消订阅
    void detach(Observer observer);
    //通知变动
    void  notifyChanged();

}

实例:

public class RealSubject implements Subject{
    //奶厂

    //本奶厂下订奶的人集合
    private List<Observer> observerList = new ArrayList<Observer>();
    //添加订阅者
    @Override

    public void attach(Observer observer) {
        observerList.add(observer);
    }
    //删除订阅者
    @Override
    public void detach(Observer observer) {
        observerList.remove(observer);
    }
    //消息通知订阅者
    @Override
    public void notifyChanged() {
        for (Observer observer : observerList) {
            observer.update();
        }
    }



}

订牛奶的:

接口:

package ObserverTest;

public interface Observer {

    /**
     * 接收变动通知
     */
    void update();
}

实例:

package ObserverTest;

public class RealObject implements Observer{
    //奶厂
    @Override
    public void update() {
        System.out.println("通知");
    }
}

测试方法:
public class mainTest {
    public static void main(String[] args) {

        Subject subject = new RealSubject(); //创建奶厂
        Observer observer = new RealObject();//创建订阅人
        subject.attach(observer);//订阅人订阅 subject奶厂
        subject.notifyChanged();//奶厂发布消息 订阅者接收
    }
}

奶厂可以管理订牛奶的,删除,添加或者发布消息

订牛奶的只能接收消息

总结:

通过定义一个抽象接口 Subject(奶厂),我们可以将 奶厂 和 订奶的人 的行为统一起来。


http://www.kler.cn/a/390183.html

相关文章:

  • Android Studio 将项目打包成apk文件
  • 数据挖掘(九)
  • pySpark乱码
  • 【QT】QSS
  • 图像处理实验二(Image Understanding and Basic Processing)
  • 使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能
  • 软件设计师 - 层次化存储
  • 大数据-216 数据挖掘 机器学习理论 - KMeans 基于轮廓系数来选择 n_clusters
  • 鸿蒙UI开发——小图标的使用
  • 使用API有效率地管理Dynadot域名,列表形式查看账户whois联系人信息
  • Dubbo负载均衡
  • Baget 私有化nuget
  • SpringBoot助力企业资产优化
  • Matlab实现鹈鹕优化算法(POA)求解路径规划问题
  • [Docker#4] 镜像仓库 | 部分常用命令
  • AI生活之我用AI处理Excel表格
  • go函数传值是值传递?还是引用传递?slice案例加图解
  • 数据分析-44-时间序列预测之深度学习方法TCN
  • Autosar CP Network Management模块规范导读
  • C#中 layout的用法
  • 易泊车牌识别相机:4S 店的智能之选
  • Spring Boot与Spring Data JPA:简化数据库操作
  • Python毕业设计选题:基于django+vue的医院挂号系统设计与实现
  • stm32 踩坑笔记
  • 通过EtherNetIP转Profinet网关实现跨品牌EthernetIP协议的PLC通讯
  • 【系统设计】数据库压缩技术详解:从基础到实践(附Redis内存优化实战案例)