《大话设计模式》笔记——设计原则及几种常见设计模式

设计模式6个原则?

1.开放闭合原则:对“扩展”开放,对“修改”闭合;在我们设计一个类的时候,尽量去预留他的功能的接口,多扩展,少修改;

2.单一职责原则:让一个类的功能尽量的不要那么复杂,当一个职责(功能)需要改变时,防止“耦合”太强,影响到其他的功能;

3.依赖倒转原则:抽象不应该依赖细节,细节应该依赖抽象;多对接口编程,必要直接去针对一个具体的类编程,让类去实现接口;

4.里氏替换原则:子类可以替换掉父类;即任何一个子类都属于父类,都能被父类引用所指向。

5.迪米特法则:最少知道原则,强调一个类不要过于依赖另一个类,不需要公开的方法属性就用private修饰,减少类之间的“”耦合。

6.接口隔离原则:让接口的功能细化,用多个接口,让每一个接口去定义一种功能,而不是让一个接口具有多个功能;

总体思想:低耦合,高内聚;多用接口少用类,让类去实现接口;让功能细化,让一个类负责一种功能;

常用的几种设计模式原理及实现?

1. 单例模式(6种):

(1)单线程,定义一个private static 实例,将构造函数修饰为private,再定义一个getInstance方法返回这个实例即可;

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        //private Constructor
    }

    public Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

(2)多线程,懒汉模式,对getInstance()方法加synchronized 修饰,太笨重,每次调用都会阻塞;

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        //private Constructor
    }

    public synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

(3)双重加锁判断非空,上一版的改进版,如果为空再加锁,多一个非空判断;

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        //private Constructor
    }

    public Singleton getInstance() {
        if (instance == null) {//第一次判断:是否需要加锁
            synchronized (Singleton.class) {
                if (instance == null) {//第二次判断:是否需要实例化
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

(4)饿汉模式,直接在声明private static时就将对象实例化出来;缺点:没有做到lazy loading;

public class Singleton {
    private static Singleton instance = new Singleton(); //在这里就已经完成实例化

    private Singleton() {
        //private Constructor
    }

    public Singleton getInstance() {
        return instance;
    }
}

(5)静态内部类实现,上一版本的改进版,也是推荐的一种;

public class Singleton {
    private Singleton() {
        //private Constructor
    }

    static class SingletonInner {
        private static Singleton instance = new Singleton();
    }

    public Singleton getInstance() {
        return SingletonInner.instance;
    }
}

(6)枚举,Enumeration天然的实现了“单例模式”(如果只有一个实例的话);

运用场景:只需要一个公用对象来保存某种状态,例如数据库连接对象Connection,只需要一个实例;“空对象”都是单例;

2. 简单工厂模式

工厂模式就是为了获得某个具体的产品类的实例;

几种工厂模式其实都差不多,区别在于工厂类是一个还是多个,根据什么返回实例(具体类名String返回对应类的实例),这个用于区别简单工厂和工厂方法;产品之间有无继承关系,存在多个产品接口,构成“产品簇”,这个用于区分抽象工厂;

工厂模式主要包括产品接口;工厂接口;产品实现类(多个);工厂实现类(一个或多个)工厂设计模式框架

interface Product {//产品接口

    void doA();

    void doB();

    void doC();
}

interface Factory {//工厂接口
    Product getProduct();
}

class ProductA implements Product {//产品实现类A

    public void doA() {
        System.out.println("A—doA");
    }

    public void doB() {
        System.out.println("A—doB");
    }

    public void doC() {
        System.out.println("A—doC");
    }
}

class ProductB implements Product {//产品实现类B

    public void doA() {
        System.out.println("B—doA");
    }

    public void doB() {
        System.out.println("B—doB");
    }

    public void doC() {
        System.out.println("B—doC");
    }
}

class FactoryImp implements Factory {//工厂实现类
    private Product p;

    public Product getProduct() {
        //p = new ...() ...具体返回哪个实例...
        return p;
    }
}

简单工厂:一个工厂实现类

class FactoryImp implements Factory {//简单工厂实现类
    private Product p;

    public Product getProduct(String name) {
        switch (name) {
            case "ProductA":
                p = new ProductA();
                ;
                break;
            case "ProductB":
                p = new ProductB();
                break;
        }
        return p;
    }
}

工厂方法模式:每个产品一个工厂

class FactoryImpA implements Factory {//工厂实现类

    public Product getProduct() {
        return new ProductA();
    }
}

class FactoryImpB implements Factory {//工厂实现类

    public Product getProduct(String name) {
        return new ProductA();
    }
}

抽象工厂模式:产品接口之间形成了“产品簇”

interface Product {//产品接口A
    void doA();
    void doB();
    void doC();
}

interface Toy {//产品接口B
    void doD();
    void doE();
    void doF();
}

interface Factory {
    Product getProduct();
    Toy getToy();
}

5.策略设计模式

利用了“多态”/里氏替换原则;

一个父类接口;几个子类实现接口的抽象方法;一个配置类,调用接口的实现类的方法;

interface Strategy {//父类接口
    void doSth();//抽象方法
}

class StrategyA implements Strategy {//子类A

    public void doSth() {
        System.out.println("doA");
    }
}

class StrategyB implements Strategy {//子类B

    public void doSth() {
        System.out.println("doB");
    }
}

class StrategyC implements Strategy {//子类C

    public void doSth() {
        System.out.println("doC");
    }
}

public class Context {//配置类

    public void doStrategy(Strategy s) {
        s.doSth();//根据实际传入的子类,调用相应的方法
    }
}

6.模板方法模式

主要是用到了抽象类(而不是接口),一部分公用方法要让子类继承(这类方法称之为模板方法),另一部分让子类自己实现;

一个抽象模板类;几个子类;

public abstract class Model {//抽象模板类

    public void doA() {//公用方法A
        System.out.println("doA");
    }

    public abstract void doB();//抽象方法B

    public abstract void doC();//抽象方法C

    public void doD() {//公用方法D
        System.out.println("doD");
    }

    public boolean hook() {//“钩子”方法,可以被子类覆盖,来控制执行process逻辑;
        return true;
    }

    public void processModel() {//执行process逻辑——模板方法
        doA();
        if (hook()) {//hock()决定了执行逻辑,子类覆盖该方法,反转执行B、C的逻辑
            doB();
        } else {
            doC();
        }
        doD();
    }
}

7.组合设计模式

类似“树”结构,来表示“部分—整体”的关系;每个子类都是一个树的结点,只不过分为树叶结点和树枝结点;

一个结点抽象类;许多树叶结点类和树枝结点类;

public abstract class Component {//结点抽象类
    String name;

    public Component(String name) {
        this.name = name;
    }

    public abstract void add(Component c);//添加子节点

    public abstract void remove(Component c);//删除子节点

    public abstract void display(int depth);//根据“深度”,打印 树结构
}

class Leaves extends Component {//叶子节点

    public Leaves(String name) {
        super(name);
    }

    public void add(Component c) {
        //方法为空
    }

    public void remove(Component c) {
        //方法为空
    }

    public void display(int depth) {
        System.out.println("Leave-" + depth + "-" +[this.name] (http://this.name/));//打印name
    }
}

class Composite extends Component {//树枝结点
    private List<Component> children = new ArrayList<Component>();//子节点列表

    public Composite(String name) {
        super(name);
    }

    public void add(Component c) {
        children.add(c);
    }

    public void remove(Component c) {
        children.remove(c);
    }

    public void display(int depth) {
        System.out.println("Composite-" + depth + "-" +[this.name] (http://this.name/));
        for (Component c : children) {
            c.display(depth + 1);//打印子节点深度,拓扑图
        }
    }
}

8.装饰设计模式

有点像“代理模式”,装饰者父类实现了装饰接口,并拥有一个装饰接口的实例;装饰者类则继承了装饰者父类,并覆盖了装饰者父类的方法(实际上是扩展了方法,再调用装饰者父类的方法);装饰者类之间可以嵌套使用;

interface Component {//装饰接口
    void operation();
}

class Decorator implements Component {//装饰者父类
    private Component c;//私有对象

    public void setComponent(Component c) {//传入一个装饰类对象
        this.c = c;
    }

    public void operation() {
        if (c != null) {
            c.operation();//调用的是c的operation();
        }
    }
}

class DecoratorA extends Decorator {//装饰者子类A

    private void methodA() {
        System.out.println("doA");//DecoratorA自身的方法
    }

    public void operation() {//这一步则实现了“装饰”/扩展 功能
        methodA();
        super.operation();
    }
}

class DecoratorB extends Decorator {
    
    private void methodB() {
        System.out.println("doB");//DecoratorB自身的方法
    }

    public void operation() {//这一步则实现了“装饰”/扩展 功能
        methodB();
        super.operation();
    }
}

9.适配器模式

适配器就是转接线,把两个不通用的接口通过适配器让他们可以通用;即一个方法需要A类参数,但这个方法内部是用B类的方法实现的,B类的对象传不进去,则需要一个适配器来转换,将B类对象封装到一个A类(子类)里面;

public class Test {//测试类

    public static void main(String[] args) {
        new Context().doSth(new Adaptor(new B()));
    }
}

class Context {//当前类

    void doSth(A a) {
        a.request();//这里需要B类的operation()方法,但无法传入B类实例
    }
}

class A {//类A

    void request() {
        System.out.println("A-doSth");
    }
}

class B {
    void operation() {
        System.out.println("B-doSth");
    }
}

class Adaptor extends A {//适配器类
    private B b;

    public Adaptor(B b) {
        this.b = b;
    }

    @Override
    void request() {//覆盖A类方法
        b.operation();
    }
}

10.代理模式(动态代理)

代理模式有点像“装饰者模式”,即代理类拥有一个真实对象类的实例,通过代理类对象,调用真实对象的方法,可以扩展真实类对象的方法,也可以拦截对真实类方法的调用;即拦截了对真实对象的直接访问;

class Person {//真实类

    void doA() {
        System.out.println("doA");
    }

    void doB() {
        System.out.println("doB");
    }

    void doC() {
        System.out.println("doC");
    }
}

class Proxy {//代理类
    private Person p;

    public Proxy(Person p) {
        this.p = p;
    }

    void doA() {
        System.out.println("A");//扩展doA()功能
        p.doA();
    }

    void doB() {
        p.doB();
    }

    void doC() {
        System.out.println("defence doC()");//拦截doC()功能
        //p.doC();
    }
}

11.观察者模式(发布-订阅模式)

包括一个被观察者(发布者)类和多个观察者类(订阅者);当“状态”发生改变,被观察者通知所有与它绑定的观察者,告诉他们当前的状态,并作出相应的反应;

interface Subject {//被观察者接口

    void addObserver(Observer o);//绑定观察者

    void removeObserver(Observer o);//解绑

    void setState(String s);//设置状态

    String getState();//返回状态值

    void notifyObserver();//通知所有观察者
}

interface Observer {//观察者接口

    void update();//观察者做出反应

    void setSubject(Subject s);//绑定一个被观察者
}

class SubjectA implements Subject {
    private List<Observer> myObserver = new ArrayList<Observer>();//绑定的观察者列表
    private String state;//状态

    public void addObserver(Observer o) {
        myObserver.add(o);
    }

    public void removeObserver(Observer o) {
        myObserver.remove(o);
    }

    public void setState(String s) {
        this.state = s;
    }

    public String getState() {
        return this.state;
    }

    public void notifyObserver() {
        for (Observer o : myObserver) {
            o.update();//所有的观察者作出反应
        }
    }
}

class ObserverA implements Observer {
    private Subject s;

    public void setSubject(Subject s) {
        this.s = s;
    }

    public void update() {
        System.out.println(s.getState());//获取最新状态值
        System.out.println("do some ReactionA.");//做出反应
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值