学习过程中问题记录及知识总结

    http://blog.csdn.net/lovelion

1、装饰设计模式-------------设计模式(结合大话设计模式和sunny博客、菜鸟编程)---设计原则

装饰模式(Decorator)

  装饰模式又名包装(Wrapper)模式

  装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

  装饰模式通过创建一个包装对象,也就是装饰,来包裹真实的对象。

  装饰模式以对客户端透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。

  装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。

  装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展是完全透明的。

装饰模式   装饰模式又叫包装模式。

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。可以在不创建更多子类的情况下,将对象的功能加以扩展。

装饰模式通过创建一个包装对象,即装饰,来包裹真实的对象。

装饰模式以对客户端透明的方式动态的给一个对象附上更多的责任,即,客户端不会觉得对象在装饰前和装饰后有什么不同。

装饰模式把客户端的调用委派到被装饰类,装饰模式的关键在于这种扩展是完全透明的。

2、适配器模式


1、http://www.cnblogs.com/wangjq/archive/2012/07/09/2582485.html

1. 概述

  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

2. 解决的问题

  即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

3. 模式中的角色

  3.1 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。

  3.2 需要适配的类(Adaptee):需要适配的类或适配者类。

  3.3 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。  

4. 模式解读

  注:在GoF的设计模式中,对适配器模式讲了两种类型,类适配器模式对象适配器模式。由于类适配器模式通过多重继承对一个接口与另一个接口进行匹配,而C#、java等语言都不支持多重继承,因而这里只是介绍对象适配器。

  4.1 适配器模式的类图

  

  4.2 适配器模式的代码实现

复制代码
    /// <summary>
    /// 定义客户端期待的接口
    /// </summary>
    public class Target
    {
        /// <summary>
        /// 使用virtual修饰以便子类可以重写
        /// </summary>
        public virtual void Request()
        {
            Console.WriteLine("This is a common request");
        }
    }

    /// <summary>
    /// 定义需要适配的类
    /// </summary>
    public class Adaptee
    {
        public void SpecificRequest()
        {
            Console.WriteLine("This is a special request.");
        }
    }

    /// <summary>
    /// 定义适配器
    /// </summary>
    public class Adapter:Target
    {
        // 建立一个私有的Adeptee对象
        private Adaptee adaptee = new Adaptee();

        /// <summary>
        /// 通过重写,表面上调用Request()方法,变成了实际调用SpecificRequest()
        /// </summary>
        public override void Request()
        {
            adaptee.SpecificRequest();
        }
    }
复制代码

  4.3 客户端代码

复制代码
    class Program
    {
        static void Main(string[] args)
        {
            // 对客户端来说,调用的就是Target的Request()
            Target target = new Adapter();
            target.Request();

            Console.Read();
        }
    }
复制代码

  运行结果

  

5. 模式总结

  5.1 优点

    5.1.1 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。

    5.1.2 复用了现存的类,解决了现存类和复用环境要求不一致的问题。

    5.1.3 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。

    5.1.4 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

  5.2 缺点

    对于对象适配器来说,更换适配器的实现过程比较复杂。

  5.3 适用场景

    5.3.1 系统需要使用现有的类,而这些类的接口不符合系统的接口。

    5.3.2 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

    5.3.3 两个类所做的事情相同或相似,但是具有不同接口的时候。

    5.3.4 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。

    5.3.5 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

6. 适配器应用举例

  6.1 使用过ADO.NET的开发人员应该都用过DataAdapter,它就是用作DataSet和数据源之间的适配器。DataAdapter通过映射Fill和Update来提供这一适配器。

  6.2 手机电源适配器


2、http://haolloyin.blog.51cto.com/1177454/346128

        适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

       适用场景:

       1、已经存在的类的接口不符合我们的需求;

       2、创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;

       3、在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。

通用类图:

 

我们生活中常常听到的是

       电源适配器,它是用于电流变换(整流)的设备。适配器的存在,就是为了将已存在的东西(接口)转换成适合我们的需要、能被我们所利用。在现实生活中,适配器更多的是作为一个中间层来实现这种转换作用。

在上面的通用类图中,Cient 类最终面对的是 Target 接口(或抽象类),它只能够使用符合这一目标标准的子类;而 Adaptee 类则是被适配的对象(也称 源角色),因为它包含specific (特殊的)操作、功能等,所以我们想要在自己的系统中使用它,将其转换成符合我们标准的类,使得 Client 类可以在透明的情况下任意选择使用 ConcreteTarget 类或是具有特殊功能的 Adatee 类。

       代码实现如下:

// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
	public void specificRequest() {
		System.out.println("被适配类具有 特殊功能...");
	}
}


// 目标接口,或称为标准接口
interface Target {
	public void request();
}

// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
	public void request() {
		System.out.println("普通类 具有 普通功能...");
	}
}

 

// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
	public void request() {
		super.specificRequest();
	}
}

 

// 测试类
public class Client {
	public static void main(String[] args) {
		// 使用普通功能类
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();
		
		// 使用特殊功能类,即适配类
		Target adapter = new Adapter();
		adapter.request();
	}
}

 测试结果:

普通类 具有 普通功能...
被适配类具有 特殊功能...

         上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。

        另外一种适配器模式是对象适配器,它不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式,类图如下:

 

代码实现如下:

// 适配器类,直接关联被适配类,同时实现标准接口
class Adapter implements Target{
	// 直接关联被适配类
	private Adaptee adaptee;
	
	// 可以通过构造函数传入具体需要适配的被适配类对象
	public Adapter (Adaptee adaptee) {
		this.adaptee = adaptee;
	}
	
	public void request() {
		// 这里是使用委托的方式完成特殊功能
		this.adaptee.specificRequest();
	}
}


// 测试类
public class Client {
	public static void main(String[] args) {
		// 使用普通功能类
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();
		
		// 使用特殊功能类,即适配类,
		// 需要先创建一个被适配类的对象作为参数
		Target adapter = new Adapter(new Adaptee());
		adapter.request();
	}
}

 测试结果与上面的一致。从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。

小结:

1、适配器模式也是一种包装模式,与之前的 Decorator 装饰模式同样具有包装的功能;此外,对象适配器模式还具有显式委托的意思在里面(其实类适配器也有这种意思,只不过比较隐含而已),那么我在认为它与 Proxy 代理模式也有点类似;

2、从上面一点对比来看, Decorator 、 Proxy、 Adapter 在实现了自身的最主要目的(这个得看各个模式的最初动机、描述)之外,都可以在包装的前后进行额外的、特殊的功能上的增减,因为我认为它们都有委托的实现意思在里面;

3、我所看的书中说适配器模式不适合在详细设计阶段使用它,它是一种补偿模式,专用来在系统后期扩展、修改时所用。


3、继承 子父类变量方法的继承、初始化

4、gc垃圾回收机制

5、抽象类、接口

       A、开闭原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计的设计原则。

       开闭原则:对扩展开放,对修改关闭,即软件实体尽量在不修改原有代码的情况下进行扩展。

       为了满足开闭原则,需要对系统进行抽象化设计,抽象化是开闭原则的基础。在java中,可以为系统定义一个相对稳定否抽象层,而将不同的实现行为移至具体的实现层完成。在java中,提供了接口、抽象类等机制可以通过他们定义系统的抽象层,再通过具体类扩展。如果需要修改系统,无需对抽象层做任何改动,只需增加新的具体类来实现新的业务功能即可实现在不修改已有代码的基础上扩展系统的功能,达到开闭原则的要求。

6、继承、多态

        B、里氏代换原则是开闭原则的具体实现手段之一。因为使用基类对象的地方都可以使用子类对象,因此在程序中尽量,使用基类类型对对象进行定义,在运行时确定其子类类型,用子类对象来替换父类对象。(多态)

    
 在使用里氏代换原则时需要注意如下几个问题:

        (1)子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。(如果一个方法只存在子类中,在父类中不提供相应的声明,则无法在以父类定义的对象中声明该方法。)

        (2)在运用里氏代换原则进行设计时,尽量将父类设计成抽象类或者接口,而子类则继承父类或者实现父接口,并实现在父类中声明的方法。而运行时,则用子类实例替换父类实例。(这样,增加新的功能时,无需修改原有子类代码,只通过增加一个新的子类,就可以实现系统的扩展。)

       (3)在java中,编译时,java编译器会检查一个程序是否符合里氏代换原则,这是一个与实现无关的、纯语法意义上的检查,但java编译器的检查是有局限的。

        C、依赖倒转原则:抽象不应该依赖于细节,而细节应该依赖抽象。即,针对接口编程,而不是针对实现编程。

        在实现依赖倒转原则,针对抽象层编程时,要将具体类的对象通过依赖注入的方式注入到其他对象中。  依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用注入的方式有三种:构造注入、setter注入、接口注入。

        在大多数情况下,开闭原则、里氏代换原则和依赖注入原则会同时出现,只是分析角度不同。开闭原则是目标、里氏代换是基础、依赖倒转是手段。

7、设计原则

D、单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。

E、接口隔离原则(Interface  Segregation Principle, ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

F、合成复用原则(Composite Reuse Principle, CRP):尽量使用对象组合,而不是继承来达到复用的目的。

迪米特法则(Law of  Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。

G、迪米特法则还有几种定义形式,包括不要和“陌生人”说话只与你的直接朋友通信等,在迪米特法则中,对于一个对象,其朋友包括以下几类:

      (1)当前对象本身(this)

      (2)以参数形式传入到当前对象方法中的对象;

      (3)当前对象的成员对象;

      (4)如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;

      (5)当前对象所创建的对象。

1  7种常用的面向对象设计原则

设计原则名称

  

使用频率

单一职责原则

(Single Responsibility Principle, SRP)

一个类只负责一个功能领域中的相应职责

★★★★☆

开闭原则

(Open-Closed Principle, OCP)

软件实体应对扩展开放,而对修改关闭

★★★★★

里氏代换原则

(Liskov Substitution Principle, LSP)

所有引用基类对象的地方能够透明地使用其子类的对象

 

★★★★★

依赖倒转原则

(Dependence  Inversion Principle, DIP)

抽象不应该依赖于细节,细节应该依赖于抽象

★★★★★

接口隔离原则

(Interface Segregation Principle, ISP)

使用多个专门的接口,而不使用单一的总接口

★★☆☆☆

合成复用原则

(Composite Reuse Principle, CRP)

尽量使用对象组合,而不是继承来达到复用的目的

 

★★★★☆

迪米特法则

(Law of Demeter, LoD)

一个软件实体应当尽可能少地与其他实体发生相互作用

★★★☆☆


8、dbutils就业班视频

9、数据机构邓俊辉、郝斌 结合大话数据结构和工具网站

10、jvm 深入理解java虚拟机













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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值