设计模式基本认知

设计模式基本认知

1设计模式的六大原则
1)开闭原则
对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能修改原有的代码,要实现热插拔的效果。为了使程序的扩展性好,易于维护和升级,我们需要使用接口的抽象类。
2)里氏代换原则
是面向对象设计的基本原则之一。 里氏代换原则说任何基类出现的地方,子类一定可以出现。只有当衍生类可以替换调基类,软件单位的功能不收到影响时,基类才能被真正复用,而衍生类也可以在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3)依赖倒转原则
是 “开-闭”原则的基础,针对接口编程,依赖于抽象而不是具体的实现类。
4)接口隔离原则
使用多个隔离的接口比使用单个接口好,降低类之间的耦合度。
5)迪米特法则(最少知道原则)
一个实体应当尽量少的和其他实体相互作用,使系统功能模块相对独立。
6)合成复用原则
尽量使用合成/聚合方式,而不是继承。

2.设计模式三大类
1)创建模型(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
2)结构型模式(7种):适配器模式,装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
3)行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

3.设计模式
1)单例模式(Singleton)
某个类只能生成一个实例,该类提供一个全局访问点供外部获取该实例,其拓展是有很多例模式。
优点:只有一个实例,节约了内存资源,提高了系统性能。
缺点:没有抽象层,不能扩展。职责过重,违背了单一性原则。

简单的懒汉式单例,但是线程不安全,在并发环境下可能出现多个实例。

//懒汉式单例类.在第一次调用的时候实例化自己 
public class Singleton {
    private Singleton() {}
    private static Singleton single=null;
    //静态工厂方法 
    public static Singleton getInstance() {
         if (single == null) {  
             single = new Singleton();
         }  
        return single;
    }

比较好的安全的懒汉式
双重检查锁定方式

public static Singleton getInstance() {
        if (singleton == null) {  
            synchronized (Singleton.class) {  
               if (singleton == null) {  
                  singleton = new Singleton(); 
               }  
            }  
        }  
        return singleton; 
     }

静态内部类方式

public class Singleton {
    private Singleton() {
    }
    private static class SingletonFactory{
        private static final Singleton instance=new Singleton();
    }
    public static final Singleton getInstance(){
        return SingletonFactory.instance;
    }
}

饿汉式单例

//饿汉式单例类.在类初始化时,已经自行实例化 
public class Singleton{
    private Singleton() {}
    private static final Singleton single = new Singleton();
    //静态工厂方法 
    public static Singleton getInstance() {
        return single;
    }
}

2)工厂方法模式
一般采用静态工厂模式,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
优点:客户端不需要创建对象,明确了各个类的职责
缺点:该工厂类负责创建所有实例,如果有新的类加入,需要不断的修改工厂类,不利于后期的维护
创建共同接口

public interface Sender {
	public void Send();
}

创建实现类

public class MailSender implements Sender {
	@Override
	public void Send() {
		System.out.println("this is mailsender!");
	}
public class SmsSender implements Sender {
    @Override
    public void Send() {
        System.out.println("this is sms sender!");
    }
}

创建静态工厂类

public class SendFactory {
	public static Sender produceMail(){
		return new MailSender();
	}
	public static Sender produceSms(){
		return new SmsSender();
	}
}

测试

public class FactoryTest {
	public static void main(String[] args) {	
		Sender sender = SendFactory.produceMail();
		sender.Send();
	}
}

3)抽象工厂模式
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则。所以我们要用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
好处:如果有新的类进来,只需要添加一个对应的具体工厂类,不影响现有代码,增加了程序的扩展性。
缺点:增加了代码量
创建共同接口。

public interface Sender {
	public void Send();
}

创建实现类

public class MailSender implements Sender {
	@Override
	public void Send() {
		System.out.println("this is mailsender!");
	}
public class SmsSender implements Sender {
    @Override
    public void Send() {
        System.out.println("this is sms sender!");
    }
}

再提供一个接口

public interface Provider {
	public Sender produce();
}

两个工厂类

 public class SendMailFactory implements Provider {
    	@Override
    	public Sender produce(){
    		return new MailSender();
    	}
}
public class SendSmsFactory implements Provider{
	@Override
	public Sender produce() {
		return new SmsSender();
	}
}

测试

public class Test {
	public static void main(String[] args) {
		Provider provider = new SendMailFactory();
		Sender sender = provider.produce();
		sender.Send();
	}
}

4)建造者模式
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。
创建共同接口

public interface Sender {
	public void Send();
}

创建实现类

public class MailSender implements Sender {
	@Override
	public void Send() {
		System.out.println("this is mailsender!");
	}
public class SmsSender implements Sender {
    @Override
    public void Send() {
        System.out.println("this is sms sender!");
    }
}

建造者类

public class Builder {
	private List<Sender> list = new ArrayList<Sender>();
	public void produceMailSender(int count){
		for(int i=0; i<count; i++){
			list.add(new MailSender());
		}
	}
	public void produceSmsSender(int count){
		for(int i=0; i<count; i++){
			list.add(new SmsSender());
		}
	}
}

测试

public class Test {
	public static void main(String[] args) {
		Builder builder = new Builder();
		builder.produceMailSender(10);
	}
}

5)适配器模式
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

类的适配器:核心思想就是:有一个被继承的父类,拥有一个方法,待适配,有一个被实现的接口,通过一个类继承父类并实现接口,把父类的方法扩展到接口中。
父类

public class Source {
    public void methodClass(){
        System.out.println("类中的方法");
    }
}

接口

interface Targetable{
    //与类中的方法一致
    public void methodClass();
    //接口的方法
    public void methodIt();
}

写一个类继承父类并实现接口

class Adapter extends Source implements Targetable{
    @Override
    public void methodIt() {
        System.out.println("接口中的方法");
    }
}

测试

class test{
    public static void main(String[] args) {
        Targetable targetable = new Adapter();
        targetable.methodIt();
        targetable.methodClass();
    }
}

对象的适配器:基本思路和类的适配器模式相同,我们写的类不继承方法对象类,而是持有那个类的实例,已达到兼容性的问题。
方法对象类

public class Source {
    public void methodClass(){
        System.out.println("类中的方法");
    }
}

接口

interface Targetable{
    //与类中的方法一致
    public void methodClass();
    //接口的方法
    public void methodIt();
}

写一个类持有方法对象类的实例并实现接口

class Adapter implements Targetable{
    private Source source;
    public Adapter(Source source) {
        this.source = source;
    }
    @Override
    public void methodClass() {
        source.methodClass();
    }
    @Override
    public void methodIt() {
        System.out.println("接口中的方法");
    }
}

测试

class test{
    public static void main(String[] args) {
        Source source = new Source();
        Targetable targetable = new Adapter(source);
        targetable.methodIt();
        targetable.methodClass();
    }
}

接口的适配器:写一个抽象类继承接口的所有方法,之后在写类继承抽象类,获取我们所需要的方法,而不是把接口中的所有方法都进行复写。
接口

interface Targetable{
    public void methodClass();
    public void methodIt();
}

抽象类

abstract class Adapter implements Targetable{
    @Override
    public void methodClass() {
        System.out.println("抽象类方法");
    }
    @Override
    public void methodIt() {
        System.out.println("抽象类方法");
    }
}

继承类一

class demo1 extends Adapter{
    @Override
    public void methodClass() {
        System.out.println("demo1");
    }
}

继承类二

class demo2 extends Adapter{
    @Override
    public void methodIt() {
        System.out.println("demo2");
    }
}

测试

class test{
    public static void main(String[] args) {
        Adapter demo1 = new demo1();
        Adapter demo2 = new demo2();
        demo1.methodClass();
        demo1.methodIt();
        demo2.methodClass();
        demo2.methodIt();
    }
}

总结三种适配器模式的应用场景:
类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例的方法就行。
接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可。

6)装饰模式
给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。
接口

interface Targetable{
    public void methodIt();
}

被装饰类

class Decorated implements Targetable{
    @Override
    public void methodIt() {
        System.out.println("被装饰者");
    }
}

装饰类

class Decorater implements Targetable{
    private Targetable targetable;
    public Decorater(Targetable targetable) {
        this.targetable = targetable;
    }
    @Override
    public void methodIt() {
        System.out.println("装饰一下在前面");
        targetable.methodIt();
        System.out.println("装饰一下在后面");
    }
}

测试

class test{
    public static void main(String[] args) {
        Targetable targetable = new Decorated();
        Targetable decorater = new Decorater(targetable);
        decorater.methodIt();
    }
}

7)代理模式
为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
接口

interface Targetable{
    public void methodIt();
}

被代理类

class Decorated implements Targetable{
    @Override
    public void methodIt() {
        System.out.println("被代理者");
    }
}

代理类

class Decorater implements Targetable {
    private Targetable targetable;
    public Decorater(Targetable targetable) {
        this.targetable = targetable;
    }
    @Override
    public void methodIt() {
        before();
        targetable.methodIt();
        after();
    }
    public void before() {
        System.out.println("代理对象执行之前");
    }
    public void after() {
        System.out.println("代理对象执行之后");
    }
}

测试

class test{
    public static void main(String[] args) {
        Targetable targetable = new Decorated();
        Targetable decorater = new Decorater(targetable);
        decorater.methodIt();
    }
}

8)观察者模式
多个对象间存在一对多关系,当一个对象发生改变时,会把这种改变通知给其他多个对象,从而影响其他对象的行为。
接口

interface Targetable {
    public void methodIt();
}

实现类一

class demo1 implements Targetable {
    @Override
    public void methodIt() {
        System.out.println("实现类一");
    }
}

实现类二

class demo2 implements Targetable {
    @Override
    public void methodIt() {
        System.out.println("实现类二");
    }
}

监控接口

interface Subject{
    public void add(Targetable targetable);
    public void delete(Targetable targetable);
    public void notifyDemo();
    public void operation();
}

监控接口实现类

abstract class AbstractSubject implements Subject{
    private Vector<Targetable> vector=new Vector<Targetable>();
    @Override
    public void add(Targetable targetable) {
        vector.add(targetable);
    }
    @Override
    public void delete(Targetable targetable) {
        vector.remove(targetable);
    }
    @Override
    public void notifyDemo() {
        Enumeration<Targetable> elements = vector.elements();
        while (elements.hasMoreElements()){
            elements.nextElement().methodIt();
        }
    }
}

主对象

class MySubject extends AbstractSubject{
    @Override
    public void operation() {
        System.out.println("基本方法");
        notifyDemo();
    }
}

测试

class test {
    public static void main(String[] args) {
        MySubject mySubject = new MySubject();
        mySubject.add(new demo1());
        mySubject.add(new demo2());
        mySubject.operation();
    }
}

整理借鉴了很多大佬写的,绝大部分借鉴于此大佬(http://blog.csdn.net/zhangerqing),其他在此无法一一说明,这只是个人用来查漏补缺的文章,如果对你有帮助我很高兴。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值