zoukankan      html  css  js  c++  java
  • UML-GoF设计模式

    我认为,本章是重点中的重点。并非23个模式都被广泛应用,其中常用和最为有效的大概有15个模式。

    1、适配器(Adapter)

    1)、使用场景

    使用一个已经存在的类,但如果他的接口,也就是他的方法和你的要求不相同时,考虑使用是适配器模式。
    
    就是说,双方都不修改自己的代码的时候,可以采用适配器模式。

    2)、结构图

    3)、相关模式

    外观对象:隐藏外部系统的资源适配器也被视为外观对象,因为资源适配器使用单一对象封装了对子系统或系统的访问。
    资源适配器:当包装对象时为不同外部接口提供适配时,该对象叫资源适配器

    4)、准则

    类名后缀为“Adapter”。

    5)、用到的GRASP原则

     2、工厂模式

    1)、使用场景

    该模式也常称为“简单工厂”或“具体工厂”。如:
    1)、存在复杂创建逻辑
    2)、为提高内聚而分离创建者职责(关注点分离)
    因此,创建称为工厂的纯虚构对象来处理这些创建职责。

    2)、结构

    一般xxxFactory应该是单实例类。

    3)、相关模式

    通常使用 单例模式 来访问工厂模式。

    由谁创建工厂呢?一般采用单例模式。

    3、单例模式

    1)、使用场景

    只有唯一实例的类即为“单实例类”。对象需要全局可见性和单点访问。
    因此,建议对类定义静态方法用以返回单实例。

    2)、相关模式

    单例模式:通常用于创建工厂对象和外观对象

    以上整合例子:

    4、策略模式

    1)、使用场景

    销售的定价策略(也可叫做规则、政策或算法)具有多样性。在一段时间内,对于所有的销售可能会有10%的折扣,后期可能会对超出200元的销售给予10%的折扣,并且还会存在其他大量的变化。
    
    因此,在单独的类中分别定义每种策略/规则/政策/算法,并且使其具有共同接口

    2 )、结构

    策略模式,共同的方法内传入的参数,通常是上下文对象,上图就是sale。

    3)、结合工厂模式

    1)、使用工厂模式创建这些策略类
    2)、使用单例模式创建工厂类。

    5、组合模式

    1)、使用场景

    如果有重叠怎么办?比如:
    1)老年人折扣20%
    2)购物金额满200元享受15%折扣
    
    因此,如何能够处理像原子对象一样,(多态的)处理一组对象或具有组合结构的对象呢?
    答:定义组合和原子对象的类,使他们具有相同的接口。

    2)、结构

    2)、相关模式

    通常与策略命令模式一起使用。

    6、外观模式

    1)、使用场景

    对一组完全不同的实现或接口(如子系统中的实现和接口)需要公共、统一的接口,隐藏掉子系统复杂的实现或接口。从而使关注点分离。
    如:slf4j、通信前置
    其与适配器的区别在于,facade模式针对同职能接口的抽象并提供公共、统一的接口,强度的是统一。而adapter模式针对的是适配不同接口且老接口不改的场景,强调的是适配

    2)、结构

    3)、例子

    class Program
        {
            static void Main(string[] args)
            {
                Facade facade = new Facade();
    
                facade.MethodA();
                facade.MethodB();
    
                Console.Read();
    
            }
        }
    
        class SubSystemOne
        {
            public void MethodOne()
            {
                Console.WriteLine(" 子系统方法一");
            }
        }
    
        class SubSystemTwo
        {
            public void MethodTwo()
            {
                Console.WriteLine(" 子系统方法二");
            }
        }
    
        class SubSystemThree
        {
            public void MethodThree()
            {
                Console.WriteLine(" 子系统方法三");
            }
        }
    
        class SubSystemFour
        {
            public void MethodFour()
            {
                Console.WriteLine(" 子系统方法四");
            }
        }
    
        class Facade
        {
            SubSystemOne one;
            SubSystemTwo two;
            SubSystemThree three;
            SubSystemFour four;
    
            public Facade()
            {
                one = new SubSystemOne();
                two = new SubSystemTwo();
                three = new SubSystemThree();
                four = new SubSystemFour();
            }
    
            public void MethodA()
            {
                Console.WriteLine("
    方法组A() ---- ");
                one.MethodOne();
                two.MethodTwo();
                four.MethodFour();
            }
    
            public void MethodB()
            {
                Console.WriteLine("
    方法组B() ---- ");
                two.MethodTwo();
                three.MethodThree();
            }
        }
    View Code

    4)、相关模式

    外观模式通常通过单例模式访问。

    7、观察者模式(Observer)

    1)、定义

    观察者模式又叫“发布-订阅(Publish/Subscribe)”模式、又叫“委派事件模型”。
    之所以被称为观察者模式,是因为监听器或订阅者在对相应事件进行观察。
    之所以被称为委派事件模型,是因为发布者将事件处理委派给了监听器(订阅者)

    2)、使用场景

    例子:支付成功后,
    1)记录日志
    2)写数据库
    3)前端展示支付结果
    传统方式,将以上3个关注点耦合在一起写。随着业务需求越来越多,导致很难维护。

    总结:当一个对象的改变需要同时改变其他对象时,而且还不知道有多少对象有待改变时,应该考虑使用观察者模式。

    3)、结构

    4)、例子

    public abstract class Subject {
        private List<Observer> observers = new ArrayList<Observer>();
        //增加观察者
        public void attach(Observer observer) {
            observers.add(observer);
        }
        //移除观察者
        public void detach(Observer observer) {
            observers.remove(observer);
        }
        //通知
        public void notify1() {
            observers.forEach(o->o.update());
        }
    }
    public abstract class Observer {
        public abstract void update();
    }
    public class ConcreteSubject extends Subject {
        private String subjectState;
    
        public String getSubjectState() {
            return subjectState;
        }
    
        public void setSubjectState(String subjectState) {
            this.subjectState = subjectState;
        }
    
    }
    public class ConcreteObserver extends Observer {
        private String name;
        private String observerState;
        private ConcreteSubject subject;
    
        public ConcreteObserver( ConcreteSubject subject,String name) {
            this.subject = subject;
            this.name = name;
        }
    
        @Override
        public void update() {
            observerState = subject.getSubjectState();
            System.out.println("观察者"+name+"的新状态是"+observerState);
        }
    
        public ConcreteSubject getSubject() {
            return subject;
        }
    
        public void setSubject(ConcreteSubject subject) {
            this.subject = subject;
        }
    }
    public class Main {
        public static void main(String[] args) {
            ConcreteSubject s = new ConcreteSubject();
    
            s.attach(new ConcreteObserver(s, "X"));
            s.attach(new ConcreteObserver(s, "Y"));
            s.attach(new ConcreteObserver(s, "Z"));
    
            s.setSubjectState("ABC");
            s.notify1();
    
        }
    }
    --输出
    观察者X的新状态是ABC
    观察者Y的新状态是ABC
    观察者Z的新状态是ABC
    View Code

    5)、小结

    A、一个事件支持多个订阅者

    public static void main(String[] args) {
        ConcreteSubject s = new ConcreteSubject();
        //多个订阅者
        s.attach(new ConcreteObserver(s, "X"));
        s.attach(new ConcreteObserver(s, "Y"));
        s.attach(new ConcreteObserver(s, "Z"));
        //一个事件
        s.setSubjectState("ABC");
        s.notify1();
    
    }

    B、订阅者可动态添加或删除

    public abstract class Subject {
        private List<Observer> observers = new ArrayList<Observer>();
        //增加观察者
        public void attach(Observer observer) {
            observers.add(observer);
        }
        //移除观察者
        public void detach(Observer observer) {
            observers.remove(observer);
        }
        //通知
        public void notify1() {
            observers.forEach(o->o.update());
        }
    }
  • 相关阅读:
    Linux之流程判断
    Linux之Shell变量
    Linux之RAID
    Y-Sport
    [ST2017] Lab1: Triangle type and Junit test
    [ST2017] Hw3: Prime Path
    [ST2017] Hw2: Fault, Error, Failure and test case for projects
    [SPM2017] Hw1: The outcome of my project [Deadline: 23:59:59, Mar.1, 2017]
    [ST2017] Hw1: An error from my past projects [Deadline: 23:59:59, Feb.27, 2017]
    一个使用Jmeter做接口性能测试的实战案例
  • 原文地址:https://www.cnblogs.com/yaoyuan2/p/11289712.html
Copyright © 2011-2022 走看看