设计模式学习

设计模式

策略模式

策略模式定义了算法族,分别封装起来,让他们之间可以互相替换 把会变化的部分取出并 "封装" 起来、让其他部分不会受到影响

使用场景

算法选择:

当有多种算法可以实现同一个功能,并且这些算法可以在运行时根据需求动态选择时。

算法封装:

当需要将算法的实现和使用它的代码分离开来时,策略模式可以将算法封装在独立的类中,使得它们可以独立地变化。

个人拙见:关键点在于对系统的拓展、超类的抽象

代码示例

Duck超类、并定义鸭子相关

java 复制代码
public abstract class Duck {
	//飞行行为抽象
    public FlyBehavior flyBehavior;
    //呼唤行为抽象
    public QuackBehavior quackBehavior;

    abstract void display();

    public void performFly() {
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }
}

抽象行为1

java 复制代码
public interface QuackBehavior {
    void quack();
}

public class Squeak implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("吱吱吱");
    }
}

抽象行为2

java 复制代码
public interface FlyBehavior {
    void fly();
}

public class FlyNoWayBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("i can't fly!");
    }
}

duck具体实现类

java 复制代码
public class FlyDuck extends Duck{


    @Override
    void display() {
        System.out.println("FlyDuck");
        super.performFly();
        super.performQuack();
    }

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        super.flyBehavior = flyBehavior;
    }

    public void setQuackBehavior(QuackBehavior quackBehavior) {
        super.quackBehavior = quackBehavior;
    }
}

策略模式测试

java 复制代码
public class StrategyTest {

    public static void main(String[] args) {
        FlyDuck duck = new FlyDuck();
        duck.setFlyBehavior(new FlyNoWayBehavior());
        duck.setQuackBehavior(new Squeak());
        duck.display();
    }
}

Duck的行为被抽取为超类不动、后续有不同的行为可以在子类使用不同的行为实现类,完成新功能勿需改动之前的代码

装饰者模式

装饰者模式 : 动态地将责任附加到对象上。 若要扩展功能,装饰者提供了比继承更有弹性 的替代方案。

优点在于可以不改变现有的代码达到对功能的拓展、但是会新增很多新业务的装饰者类、业务场景越多对应的装饰者越多。

应用了开闭原则编程思想、利用组合的方式、动态的将类的拓展,满足各种复杂的业务场景,相对于继承显得更加灵活,只需要一层一层的装饰、就能获得想要的业务对象

应用场景

在Java的I/O系统中,装饰者模式得到了广泛应用。例如,BufferedReader和BufferedWriter是对字符输入/输出流的装饰,它们提供了缓冲功能,从而提高了读写效率。此外,InputStreamReader和OutputStreamWriter也是装饰者模式的典型应用,它们将字节流转换为字符流,便于进行字符级别的操作。

相对于继承显得更加灵活,只需要一层一层的装饰、就能获得想要的业务对象

开闭原则

代码示例

java 复制代码
/**
 *  饮料基类
 */
public abstract class Beverage {
    String description = "Unknown Beverage";
    public String getDescription() {
        return description;
    }
    public abstract double cost();
}
java 复制代码
/**
 *  调料基类
 */
public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();
}

饮料1

java 复制代码
/**
 * 浓缩咖啡
 */
public class Espresso extends Beverage{
    @Override
    public String getDescription() {
        return "Espresso 浓缩咖啡";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}

调料1

java 复制代码
public class Mocha extends CondimentDecorator{

    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }


    @Override
    public double cost() {
        return 1.00 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",mocha";
    }
}

调料2

java 复制代码
public class Whip extends CondimentDecorator{

    Beverage beverage;

    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }


    @Override
    public double cost() {
        return 0.50 + beverage.cost();
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",whip";
    }
}

测试类

java 复制代码
    public static void main(String[] args) {

        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription()+",$"+beverage.cost());
        beverage = new Mocha(beverage);
        System.out.println(beverage.getDescription()+",$"+beverage.cost());
        beverage = new Whip(beverage);
        System.out.println(beverage.getDescription()+",$"+beverage.cost());

    }

适配器/外观模式

适配器模式 将一个类的接口,转换成客户期望的另一 个接口。适配器让原本接口不兼容的类可以合作无间。

这个模式可以通过创建适配器进行接口转换,让不兼容的接口变成兼容。这可以让客户从实现的接口解耦。

如果在一段时间之后,我们想要改变接口,适配器可以将改变的部分封装起来,客户就不必为了应对不同的

接口而每次跟着修改。

对象适配器-组合和类适配器-继承使用两种不同的适配方法。

客户端需要一个 Target 接口的 request() 方法,但现有类 Adaptee 只有 specificRequest() 方法,需要通过适配器转换。

组合

java 复制代码
// 目标接口(同上)
interface Target {
    void request();
}

// 被适配类(同上)
class Adaptee {
    void specificRequest() {
        System.out.println("执行被适配类的具体方法");
    }
}

// 对象适配器:持有被适配类的实例,实现目标接口
class ObjectAdapter implements Target {
    private Adaptee adaptee; // 组合被适配对象

    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        // 调用被适配对象的方法,转换为目标接口的方法
        adaptee.specificRequest();
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee); // 传入被适配对象
        target.request(); // 输出:执行被适配类的具体方法
    }
}

继承

java 复制代码
// 目标接口:客户端期望的接口
interface Target {
    void request();
}

// 被适配类:已有但接口不兼容的类
class Adaptee {
    void specificRequest() {
        System.out.println("执行被适配类的具体方法");
    }
}

// 类适配器:继承被适配类,实现目标接口
class ClassAdapter extends Adaptee implements Target {
    @Override
    public void request() {
        // 复用父类(Adaptee)的方法,转换为目标接口的方法
        super.specificRequest();
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Target target = new ClassAdapter();
        target.request(); // 输出:执行被适配类的具体方法
    }
}

最少知识原则

这个原则希望我们在设计中,不要让太多的类耦合在一 起,免得修改系统中一部分,会影响到其他部分。如果许 多类之间相互依赖,那么这个系统就会变成一个易碎的系 统,它需要花许多成本维护,也会因为太复杂而不容易被 其他人了解。

外观模式

外观模式外观模式提供了一个统一的接口,用来访问子系统中 的一群接口。外观定又了一个高层接口,让子系统更容易 使用。

相关推荐
神奇的代码在哪里1 小时前
C++的演进与我的编程学习之旅:从底层基础到AI应用
c++·人工智能·python·学习·程序人生·个人开发
guts3501 小时前
【anylogic】官方地铁入口教程学习记录(行人库)
学习·anylogic
记忆偶然1 小时前
语音转文本技术实践:主流工具特性解析与应用场景探讨
人工智能·学习·语音识别
Mai Dang2 小时前
黑马Mybatis-Plus学习笔记
笔记·学习·mybatis
YJlio2 小时前
第9章小结(9.19):Sysinternals 安全工具组合拳与脚本清单
java·学习·平面
xian_wwq2 小时前
【学习笔记】网络安全死于平庸
笔记·学习·安全防护
d111111111d2 小时前
在STM32F103C8T6中什么是读写寄存器模型,有什么用,可以干什么,详细解释。
笔记·stm32·单片机·嵌入式硬件·学习
金士顿2 小时前
DI滤波学习
学习
qq_401780822 小时前
1.信号完整性(方波信号的频谱特征)
学习