首页 > 编程语言 >Java设计模式_1(10/23)

Java设计模式_1(10/23)

时间:2024-02-02 14:13:15浏览次数:25  
标签:10 Java String void 模式 public new 设计模式 class

Java设计模式_1(10/23)

目录

单例模式

定义

确保类只有一个实例,而且自行实例化并向整个系统提供这个实例。

  1. 一个类只有一个实例:构造方法一定不是Public公开的,即Private
  2. 构造出来的实例是类成员变量,即静态变量
  3. 再提供一个方法,用于外界访问这个实例

应用点:

  1. 序列号生成器、Web页面计数器

  2. 创建一个对象需要消耗很多资源,如:访问IO、数据库资源

饿汉式

public class SingletonPattern {
    public static void main(String[] args){
    }
}

class Singleton {
    private static Singleton singleton = new Singleton(); // 饿汉式实现,使用这个对象的时候,立马就能够创建
    private Singleton() {
    }
    public static Singleton getInstance() {  // 仅此public公开
        return singleton;
    }
}

懒汉式

public class SingletonPattern {
    public static void main(String[] args){
    }
}

class Singleton {
    private static Singleton singleton;
    private Singleton() {
    }
    public synchronized static Singleton getInstance() {  // 加锁,避免多次实例化
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

懒汉式(双重检查锁)

public class SingletonPattern {
    public static void main(String[] args){
    }
}

class Singleton {
    private volatile static Singleton singleton;  // volatile 保证线程可见性,保证线程安全
    private Singleton() {
    }
    public static Singleton getInstance() {  
        if (singleton == null) {
            synchronized (Singleton.class) { // 如果singletone还没有初始化,这个时候用synchronized来同步加锁,再判断一次是否为空,来实例化对象
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

注:volatile这个关键字的作用

  • Java语言提供了一种稍弱同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

  • 在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。

  • 声明变量是 volatile 的,JVM 保证了每次读变量都从内存中读,跳过 CPU cache 这一步。

singleton = new Singleton()可拆解为3步:分配内存、初始化对象、指向刚分配地址

  • 若发生重排序,则先指向刚分配地址初始化对象这个时候就乱了。所以在双重检查锁的时候需要加上volatile修饰。

  • 说白了就是在这里禁止重新排序。

单例模式最佳实现就是无状态的,不然这里调用一下赋值20,另一边调用赋值30,凡是用到这里的,都会因为改变而改变。

简单工厂模式

定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单工厂模式是用来创建某一大类下面不同类的实例的一种模式。

classDiagram Product <|.. ProductA Product <|.. ProductB ProductA <.. Factory:Use ProductB <.. Factory:Use class Product{ <<Abstract>> + method() } class ProductA{ + method() } class ProductB{ + methond() } class Factory{ + createProduct(string):Product }

代码

public class SimpleFactory {
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ProductA();
        } else if (type.equals("B")) {
            return new ProductB();
        } else {
            return null;
        }
    }

    public static void main(String[] args) { // 调用方法
        Product Product = SimpleFactory.createProduct("A");
        Product.print();
    }
}

abstract class Product {  // 定义一个抽象类
    public abstract void print();
}

class ProductA extends Product { // 负责具体的实现
    @Override
    public void print() {
        System.out.println("ProductA");
    }
}

class ProductB extends Product { // 负责具体的实现
    @Override
    public void print() {
        System.out.println("ProductB");
    }
}

优点

实现对象的创建和使用分离,创建交给专门的工厂类负责,客户端程序员不关心怎么创建,只关心如何使用。

缺点

工厂类不够灵活,如果要新增一个产品就需要修改工厂类,违反了开闭原则。

工厂模式

类似于把多个简单工厂给管理在一起,形成了一个大的工厂,并定义一个接口。

定义

定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。

classDiagram Factory <|.. FactoryAB Factory <|.. FactoryA Product <|.. ProductA Product <|.. ProductB ProductA <-- FactoryA:create ProductB <-- FactoryAB:create class ProductA { + method() } class ProductB { + method() } class FactoryAB { + createProduct(string): Product } class FactoryA { + createProduct(string): Product } class Product { <<Abstract>> + method() } class Factory { <<Abstract>> + createProduct(string): Product }
public calss FactoryPattern {
    public static void main(String[] args) {
    }
}

interface Phone {
    void print();
}

class iPhone implements Phone {
    @Override
    public void print() {
        System.out.println("iPhone");
    }
}

class HuaWeiPhone implements Phone {
    @Override
    public void print() {
        System.out.println("HuaWeiPhone");
    }
}

interface Factory {
    Phone createPhone();
}

class IPhoneFactory implements Factory {
    @Override
    public Phone createPhone() {
        return new iPhone();
    }
}

class HuaWeiPhoneFactory implements Factory {
    @Override
    public Phone createPhone() {
        return new HuaWeiPhone();
    }
}

抽象工厂模式

类似于把多个工厂给管理在一起,形成了一个大的工厂,并定义一个接口。

classDiagram Phone <|.. IPhone Phone <|.. HuaWei Factory <|.. FactoryA Factory <|.. FactoryB Mask <|.. N95 Mask <|.. KN90 FactoryB <-- HuaWei FactoryB <-- KN90 FactoryA <-- IPhone FactoryA <-- N95 class Phone { <<Abstract>> + method() } class IPhone { + method() } class HuaWei { + method() } class Mask { <<Abstract>> + method() } class N95 { + method() } class KN90 { + method() } class Factory { <<Abstract>> + createPhone(string): Phone + createMask(string): Mask } class FactoryB { + createPhone(string): Phone + createMask(string): Mask } class FactoryA { + createPhone(string): Phone + createMask(string): Mask }
// 抽象工厂
interface AbstractFactory {
    Phone createPhone(String param);
    Mask createMask(String param);
}

// 具体工厂
class SuperFactory implements AbstractFactory {
    @override
    Phone createPhone(String param) {
        return new iphone();
    }

    @Override
    Mask createMask(String param) {
        return new N95();
    }
}

//产品大类 手机
interface Phone {}
class iPhone implements Phone {}

interface Mask {}
class N95 implements Mask {}

简单工厂xN = 工厂x1 => 工厂xN = 抽象工厂x1

装饰器模式

动态地给一个对象添加一些额外的功能。就增加功能来说,装饰器模式比生成子类更加灵活。

classDiagram Component <|.. ConcreateComponent Component <|.. Decorator Decorator <|.. ConcreateDecorator Decorator o-- Component class Component { + method() } class ConcreateComponent { + method() } class Decorator { + method() } class ConcreateDecorator { + method() }
public class DecoratorPattern {
    public static void main(String[] args) {
        new RobotDecorator(new FirstRobot()).doMoreThing();
    }
}

interface Robot {
    void doSomething();
}

class FirstRobot implements Robot {
    @Override
    public void doSomething() {
        System.out.println("对话");
        System.out.println("唱歌");
    }
}

class RobotDecorator implements Robot {
    private Robot robot;

    public RobotDecorator(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void doSomething() {
        robot.doSomething();
    }

    public void doMoreThing() {
        robot.doSomething();
        System.out.println("跳舞、拖地");
    }
}

javaIO流也使用了装饰器模式

适配器模式

将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

classDiagram Target <|.. Adapter Adapter o-- Adaptee class Target { <<Interface>> + request(): Type } class Adapter { + request(): Type } class Adaptee { +specificRequest(): Type } classDiagram Target <|.. Adapter Adaptee <-- Adapter: Extends class Target { <<Interface>> + request(): Type } class Adapter { + request(): Type } class Adaptee { +specificRequest(): Type }

适配器突出适配,适配器模式会改变原有的实例方法,是改变而不是新增。<会改变接口>

装饰器模式不会改变原有的实例方法,只会新增。<不会改变接口>

public class AdapterPattern {
    public static void main(String[] args) {
        new Adapter(new Speaker()).translate();
    }
}

class Speaker {
    public String speak() {
        return "China No.1";
    }
}

interface Translator {
    public String translate();
}

class Adapter implements Translator {
    private Speaker speaker;
    public Adapter(Speaker speaker) {
        this.speaker = speaker;
    }
    @Override
    public String translate() {
        String result = speaker.speak();
        return null;
    }
}

观察者模式

定义

观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变是,其相关依赖对象借的到通知并自动更新。

classDiagram Debit <|.. ZhangSan Credit <|.. Wangwu Credit <|.. Zhaosi class Debit { <<Interface>> + borrow(Credit) + notifyCredits() } class ZhangSan { + borrow(Credit) + notifyCredits() } class Credit { <<Interface>> + takeMoney() } class Wangwu { + takeMoney() } class Zhaosi { + takeMoney() }
public class Observer Pattern {
    public static void main(String[] args) {
        Debit ZhangSan = new ZhangSan();
        ZhangSan.borrow(new Wangwu());
        ZhangSan.borrow(new Zhaosi());
        //state change
        ZhangSan.notifyCredits();
}

interface Debit {
    void borrow(Credit credit);
    void notifyCredits();
}

class ZhangSan implements Debit {
    private List<Credit> allCredits = new ArrayList<>();
    private Integer state = 0; // 1 表示有钱

    @Override
    public void borrow(Credit credit) {
        allCredits.add(credit);
    }

    @Override
    public void notifyCredits() {
        allCredits.forEach(Credit -> Credit.takeMoney());
    }
}

interface Credit {
    void takeMoney();
}

class Wangwu implements Credit {
    @Override
    public void takeMoney() {
        System.out.println("Wangwu take money");
    }
}

class Zhaosi implements Credit {
    @Override
    public void takeMoney() {
        System.out.println("Zhaosi take money");
    }
}

外观模式

定义

说白了就隐藏内部细节,对外提供一个方法

要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。

外观模式提供一个高层次的接口,使得子系统更容易使用。

classDiagram Facade <|.. SubSystemOne Facade <|.. SubSystemTwo Facade <|.. SubSystemThird class Facade { + methodA() + methodB() } class SubSystemOne { + methodOne() } class SubSystemTwo { + methodTwo() } class SubSystemThird { + methodthree() }
public class FacadePattern {
    public static void main(String[] args) {
        new Facade().prove();
    }
}

class SubFlow1 {
    boolean isTrue() {
        return true;
    }
}

class SubFlow2 {
    boolean isOk() {
        return true;
    }
}

class SubFlow3 {
    boolean isMan() {
        return true;
    }
}

class Facade {
    SubFlow1 s1 = new SubFlow1();
    SubFlow2 s2 = new SubFlow2();
    SubFlow3 s3 = new SubFlow3();
    boolean prove() {
        return s1.isTrue() && s2.isOk() && s3.isMan();
    }
}

缺点:违反了开闭原则

状态模式

定义

状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其类别名为状态对象(Objects for States),状态模式是一种对象行为型模式。

classDiagram Context o-- State State <-- Context State <|-- ConcreteStateA State <|-- ConcreteStateB class Context { +changeState(State *):void +request():void } class State { +handle():void } class ConcreteStateA { +handle():void } class ConcreteStateB { +handle():void }
public class StatePattern {
    public static void main(String[] args) {
        Context ZhangSan = new Context();
        ZhangSan.changeState(new Happy());
        ZhangSan.doSomething();
        ZhangSan.changeState(new Sad());
        ZhangSan.doSomething();
        ZhangSan.changeState(new Angry());
        ZhangSan.doSomething();
    }
}

abstract class State {
    abstract void doWork();
}

class Happy extends State {
    @Override
    void doWork() {
        System.out.println("Happy");
    }
}

class Angry extends State {
    @Override
    void doWork() {
        System.out.println("Angry");
    }
}

class Sad extends State {
    @Override
    void doWork() {
        System.out.println("Sad");
    }
}

class Context {
    private State state;
    public void changeState(State state) {
        this.state = state;
    }

    public void doSomething() {
        state.doWork();
    }
}

优点:封装了转换规则,并枚举了可能的状态,它将所有与某个对状态有关的行为,放到了状态类中,并且可以方便地增加新的状态。还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点:会增加系统(状态)类和(状态)对象的个数,使用不当会导致程序结构或代码的混乱。

策略模式

定义

定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)

状态VS策略

状态强调的状态的不同,状态不同要做的事情不同(开心->买肯德基犒劳犒劳自己,不开心->明天请假不上班),聚焦在开心或者不开心上,而开心或者不开心具体要做什么不关心,你不开心明天辞职也可以。

策略强调要做的事情不同会导致做事情的具体步骤不同,强调的是“做的步骤”,即行为、算法本身。

classDiagram Context o-- Strategy Strategy <|.. ConcreteStrategyA Strategy <|.. ConcreteStrategyB class Context { +algorithm(): void +setStrategy(Strategy*): void } class Strategy { +algorithm():void } class ConcreteStrategyA { +algorithm():void } class ConcreteStrategyB { +algorithm():void }

代理模式

标签:10,Java,String,void,模式,public,new,设计模式,class
From: https://www.cnblogs.com/tongering/p/18003073

相关文章

  • 设计模式浅析(一) ·策略模式
    设计模式浅析(一)·策略模式日常叨逼叨java设计模式浅析,如果觉得对你有帮助,记得一键三连,谢谢各位观众老爷......
  • Java 中的List
    ListList接口常用方法List集合存储元素特点:有序可重复List既然是Collection接口的子接口,那么肯定List接口有自己的“特色”方法以下列出List特有的常用的方法:voidadd(intindex,Eelement)将指定的元素插入此列表中的指定位置(可选操作)。Objectget(intindex)返回......
  • 四端口 10/100/1000BASE-T PHY,VSC8564XKS-11、VSC8564XKS-14、VSC8584XKS-14、VSC8584
    一、VSC8564 四端口10/100/1000BASE-TPHY,带同步以太网、Intellisec™和QSGMII/SGMIIMAC说明VSC8564采用IntelliSec的四端口GBEPHY非常适合保护云网络应用,例如电子商务、数据库、协作、智能电网、视频和企业或政府通信。此外,VSC8564可以添加到符合FIPS140-2标准的产品设计......
  • UVA1109/Gym101175I Mummy Madness
    题意简述你初始在\((0,0)\),每个时刻你能向八连通格子移动或不移动。有\(n\)个怪物,怪物坐标已知,每个时刻怪物也能向八连通格子移动或不移动,而且会选择最终与你欧几里得距离最短的一种方案。求你在什么时刻会被怪物抓住(你和怪物在同一格子内),或报告无解。\(n\le10^5,|x_i|,|y......
  • java: Compilation failed: internal java compiler error
    idea启动项目后出现 java:Compilationfailed:internaljavacompilererror错误第一种情况:idea的JDK版本和项目配置的不同。解决方法:查看项目中配置的jdk版本,再查看 idea配置的版本项目配置的:在idea中要查看三个地方的配置 1、File---->Setting------>javacompile......
  • 深入浅出Java多线程(六):Java内存模型
    引言大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第六篇内容:Java内存模型。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!!在并发编程中,有两个关键问题至关重要,它们是线程间通信机制和线程间同步控制。线程间通信机制线程间通信是指在一个多线程程序......
  • 深入浅出Java多线程(八):volatile
    引言大家好,我是你们的老伙计秀才!今天带来的是[深入浅出Java多线程]系列的第八篇内容:volatile。大家觉得有用请点赞,喜欢请关注!秀才在此谢过大家了!!!在当今的软件开发领域,多线程编程已经成为提高系统性能和响应速度的重要手段。Java作为广泛应用的多线程支持语言,其内存模型(JMM)设计巧妙......
  • WPF 客户端设计(MVVM设计模式)
    WPF(WindowsPresentationFoundation)是微软推出的基于Windows的用户界面框架。在这里我设计了一份以MVVM设计模式下的纯桌面端应用架构,期间包含界面初始化流程,菜单加载及页面跳转流程等。以下来详细说明下设计方式:期间项目使用到了我自己上传到Nuget的包:目录1:启动2:主界面2.1......
  • 10个Pandas的高级技巧
    Pandas是我们最常用的数据处理Python库之一。尽管您可能已经与它共事多年,但可能还有许多您尚未探索的实用方法。我将向您展示一些可能未曾听说但在数据整理方面非常实用的方法。我目前日常使用的是pandas2.2.0,这是本文时可用的最新版本。https://avoid.overfit.cn/post/2baf15......
  • POCO编译报错:LNK1104 无法打开文件“libcrypto.lib”
    POCO编译报错1>LINK:fatalerrorLNK1104:无法打开文件“libcrypto.lib” 解决:1、项目  ->  属性  ->  C/C++ -> 常规 -> 附加包含目录,添加OPENSSL头文件路径C:\ProgramFiles\OpenSSL-Win64\include(OPENSSL安装路径) 2、项目  ->  属......