设计模式
策略模式
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换 把会变化的部分取出并 "封装" 起来、让其他部分不会受到影响
使用场景
算法选择:
当有多种算法可以实现同一个功能,并且这些算法可以在运行时根据需求动态选择时。
算法封装:
当需要将算法的实现和使用它的代码分离开来时,策略模式可以将算法封装在独立的类中,使得它们可以独立地变化。
个人拙见:关键点在于对系统的拓展、超类的抽象
代码示例
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(); // 输出:执行被适配类的具体方法
}
}
最少知识原则
这个原则希望我们在设计中,不要让太多的类耦合在一 起,免得修改系统中一部分,会影响到其他部分。如果许 多类之间相互依赖,那么这个系统就会变成一个易碎的系 统,它需要花许多成本维护,也会因为太复杂而不容易被 其他人了解。

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