美文网首页
设计模式

设计模式

作者: _Felix__ | 来源:发表于2019-05-16 00:14 被阅读0次

    前言:在学习早期,你读不懂别人的代码,改不动别的代码的绝大数情况下,是因为你没有别人的架构思维,你对java设计模式一无所知

    学习的书籍:HeadFirst设计模式

    书籍源码可在官网下载https://www.wickedlysmart.com/head-first-design-patterns/

    github上相关的一个优秀项目:https://github.com/iluwatar/java-design-patterns


    观察者模式

    观察者模式类图

    何时适用?

    • 当抽象有两个方面时,一个依赖于另一个。将这些方面封装在单独的对象中可以让您独立地改变和重用它们
    • 当对一个对象的更改需要更改其他对象,而您不知道有多少对象需要更改时
    • 当一个对象应该能够通知其他对象而不用假设这些对象是谁时。换句话说,你不希望这些对象紧密耦合
      一个对象的变化会导致其他对象的变化

    真实应用场合

    代码示例

    public class Example {
        public static void main(String[] args) {
            SimpleSubject simpleSubject = new SimpleSubject();
            SimpleObserver simpleObserver = new SimpleObserver(simpleSubject);
            simpleSubject.setValue(80);//1.主题的数据发生了变化。
        }
    }
    
    public interface Subject {
        public void registerObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyObservers();
    }
    
    public interface Observer {
        public void update(int value);
    }
    
    public class SimpleSubject implements Subject {
        private ArrayList<Observer> observers;
        private int value = 0;
        
        public SimpleSubject() {
            observers = new ArrayList<Observer>();
        }
        
        public void registerObserver(Observer o) {
            observers.add(o);
        }
        
        public void removeObserver(Observer o) {
            int i = observers.indexOf(o);
            if (i >= 0) {
                observers.remove(i);
            }
        }
        
        public void notifyObservers() {
        /*3.for循环通知(实现)所有观察者进行update操作(只要你订阅了我,别想跑)*/
            for (Observer observer : observers) {
                observer.update(value);
            }
        }
        //2.通知观察者
        public void setValue(int value) {
            this.value = value;
            notifyObservers();
        }
    }
    
    public class SimpleObserver implements Observer {
        private int value;
        private Subject simpleSubject;
        
        public SimpleObserver(Subject simpleSubject) {
            this.simpleSubject = simpleSubject;
            //0.观察者首先得订阅
            simpleSubject.registerObserver(this);
        }
        //4.更新并显示,(流程走完)。
        public void update(int value) {
            this.value = value;
            display();
        }
        
        public void display() {
            System.out.println("Value: " + value);
        }
    }
    
    
    

    装饰着模式(Wrapper)

    在面向对象编程中,装饰模式是一种设计模式,它允许将行为静态或动态地添加到单个对象中,而不影响同一类中其他对象的行为。装饰模式对于坚持单一责任原则通常很有用,因为它允许在具有独特关注领域的类之间划分功能。


    装饰者模式类图

    何时适用?

    • 动态透明地向单个对象添加责任,即不影响其他对象
    • 对于可以撤回的责任
    • 当子类化扩展不切实际时。有时大量独立的扩展是可能的,并且会产生子类的爆炸来支持每一种组合。或者类定义可能被隐藏或者不可用于子类化

    真实应用场景

    代码示例

    public class StarbuzzCoffee {
        public static void main(String args[]) {
            Beverage beverage = new Espresso();
            System.out.println(beverage.getDescription() 
                    + " $" + beverage.cost());
            /*
            不太懂这一块。 
            */
            Beverage beverage2 = new Espresso();
            beverage2 = new Mocha(beverage2);
            beverage2 = new Mocha(beverage2);
            beverage2 = new Whip(beverage2);
            System.out.println(beverage2.getDescription() 
                    + " $" + beverage2.cost());
        }
    }
    
    //抽象类本身不能被实例化
    public abstract class Beverage {
        String description = "Unknown Beverage";
      
        public String getDescription() {
            return description;
        }
        //提供一个抽象方法,子类实现。
        public abstract double cost();
    }
    
    public abstract class CondimentDecorator extends Beverage {
        Beverage beverage;
        public abstract String getDescription();
    }
    
    public class Espresso extends Beverage {
      
        public Espresso() {
            description = "Espresso";
        }
      
        public double cost() {
            return 1.99;
        }
    }
    
    public class Mocha extends CondimentDecorator {
        public Mocha(Beverage beverage) {
            this.beverage = beverage;
        }
     
        public String getDescription() {
            return beverage.getDescription() + ", Mocha";
        }
     
        public double cost() {
            return .20 + beverage.cost();
        }
    }
    
    public class Whip extends CondimentDecorator {
        public Whip(Beverage beverage) {
            this.beverage = beverage;
        }
     
        public String getDescription() {
            return beverage.getDescription() + ", Whip";
        }
     
        public double cost() {
            return .10 + beverage.cost();
        }
    }
    

    工厂模式

    依赖倒置原则

    糟糕的情况
    依赖倒置原则
    • 如何避免在OO设计中违反依赖倒置原则
      • 变量不可以持有具体类的引用
      • 不要让类派生自具体类
      • 不要覆盖基类中已实现的方法

    何时适用


    单件模式


    命令模式

    命令模式将“请求”封装成对象,以便使用不用的请求、队列或者日志来参数化其他对象。命令模式也支持撤销的操作。

    image.png

    何时适用

    • 意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
    • 主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
    • 何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
    • 如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
    • 关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口
    • 应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。
    • 优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
    • 缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
    • 使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。
    • 注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。

    真实应用场景

    代码示例

    public interface Command {
        public void execute();
    }
    
    public class LightOnCommand implements Command {
        Light light;
        public LightOnCommand (Light light) {
            this.light = light;
        }
        public void execute(){
            light.on();
        }
    }
    
     public class SimpleRemoteControl {
        Command slot;
        public SimpleRemoteControl () {};
        public void setCommand(Command command){
            slot = command;
        }
        public void buttonWasPressed(){
            slot.execute( );
        }
    }
     
    public  class RemoteControlTest{
        public static void main (String [] args){
            SimpleRemoteControl remote = new SimpleRemoteControl();
            Light light = new Light();
            LightOnCommand lightOn = new LightOnCommand(light);
            remote.setCommand(lightOn);
            remote.buttonWasPressed();
        }
    }
    

    相关文章

      网友评论

          本文标题:设计模式

          本文链接:https://www.haomeiwen.com/subject/lyyvaqtx.html