面向对象设计原则
1.单一职责原则(高内聚,低耦合)
每个类应该只有一个职责,对外只能提供一种功能,而引起类变化的原因应该只有一个。这设计模式中,所有的设计模式都遵循这一原则。
2.开闭原则
一个对象对扩展开放,对修改关闭(对类的改动通过增加代码进行,而不是修改现有代码)
这就需要借助于抽象和多态,即把可能变化的内容抽象出来,从而使抽象的部分是相对稳定的,而具体的实现则是可以改变和扩展的
3.里氏替换原则
在任何父类出现的地方都可以用他的子类来替代(同一个继承体系中的对象应该具有共同的行为特征)
4.依赖注入原则
要依赖于抽象,而不是具体实现类(针对抽象类或者接口编程)
5.接口分离原则
不应该强迫程序依赖他们不需要使用的方法(一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能)
6.迪米特原则
一个对象应当对其他对象尽可能少的了解(降低各个对象之间的耦合,提高系统的可维护性)
Java的设计模式
一、静态工厂方法模式(简单工厂模式)
1.概述:它定义一个具体的工厂类负责创建一些类的实例
2.特点:(1)构造方法私有化,外界不能直接创建对象
(2)提供静态的功能,每一种静态功能都会产生所需要的对象
3.优点:客户端不再负责对象的创建,从而明确了各个类的职责
4.缺点:不利于后期维护(如果添加新的对象,或者某些对象的创建方式不同就需要不断的修改工厂类)
例:
/*
* 静态工厂方法模式
* */
public class Test {
public static void main(String[] args){
// 产生Dog和Cat对象,并调用方法
Animal a = AnimalFactory.createAnimal("dog");
a.eat();
a = AnimalFactory.createAnimal("cat");
a.eat();
// 若没有该动物则需提供非空判断,否则会报空指针异常
a = AnimalFactory.createAnimal("pig");
if(a != null){
a.eat();
}else{
System.out.println("工厂类里还没有提供该动物");
}
}
}
// 动物的工厂类
public class AnimalFactory {
// 私有化构造方法:不让外界创建对象
private AnimalFactory(){
}
/*
方法1:
public static Dog createDog(){
return new Dog();
}
public static Cat createCat(){
return new Cat();
}
*/
// 方法2:静态方法,提供猫和狗的两个对象
public static Animal createAnimal(String type){
if("dog".equals(type)){
return new Dog();
}else if("cat".equals(type)){
return new Cat();
}else{
return null;
}
}
}
public interface Animal {
public abstract void eat();
}
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Cat implements Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
二、工厂方法模式
1.概述:工厂方法模式中抽象工厂类负责定义创建对象的接口,具体对象的创建工作由继承抽象工厂的具体类实现。
2.优点:客户端不需要在负责对象的创建,从而明确了各个类的职责,如果有新的对象增加,只需要增加一个具体的类和具体的工厂类即可,不影响已有的代码,后期维护容易,增强了系统的扩展性
3.缺点:需要额外的编写代码,增加了工作量
例:
// 测试类
public class AnimalTest {
public static void main(String[] args){
// 创建DogFactory对象
DogFactory df = new DogFactory();
// 产生Dog对象
Animal Dog = df.creatAnimal();
// 调用方法
Dog.eat();
// 产生CatFactory对象
CatFactory cf = new CatFactory();
Animal Cat = cf.creatAnimal();
Cat.eat();
}
}
/*
* 工厂方法模式
* */
public interface AnimalFactory {
public abstract Animal creatAnimal();
}
// 狗的工厂类
public class DogFactory implements AnimalFactory {
@Override
public Animal creatAnimal() {
return new Dog();
}
}
//猫的工厂类
public class CatFactory implements AnimalFactory {
@Override
public Animal creatAnimal() {
return new Cat();
}
}
public abstract class Animal {
public abstract void eat();
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
三、单例模式
概述:类在内存中存在一个对象,该实例必须自动创建,并且对外提供
注意:(1)开发中使用——“饿汉式”(不会出现问题的单例模式)
(2)面试时使用——“懒汉式”(会产生线程安全的问题)
*类中的变量应用private关键字,目的是防止外界修改变量!
*单例模式产生的都为同一对象
1.饿汉式:
(1)当前类一加载,就会创建对象
(2)将该类的无参构造私有化
(3)在成员变量位置处创建该类的实例
(4)需要提供公共的访问方法
2.懒汉式(“延迟加载”的思想):
(1)并不是类一加载就会创建对象,而是在需要的时候再创建对象(2)懒加载(延迟加载)
注:懒汉式会产生线程的安全问题:使用同步代码块进行解决!
例1:饿汉式
/*
* 单例模式之饿汉式
* */
public class StudnetTest {
public static void main(String[] args) {
// 利用Student类中静态的访问方法去创建对象
Student s1 = Student.getStudent();
Student s2 = Student.getStudent();
System.out.println("s1="+s1);
System.out.println("s2="+s2);
System.out.println(s1 == s2);
}
}
public class Student {
// 无参构造私有化,目的是为了不让外界创建对象
private Student() {
}
// 在成员变量的位置创建该类的实例,在静态方法中访问,所以需要给s加上静态修饰,private的目的是为了不让外界修改
private static Student s = new Student();
// 公共的访问方法
public static Student getStudent() {
return s;
}
}
注:<1>此种方法类产生的对象都为同一对象
<2>变量s应使用private修饰,防止外界修改
例2:懒汉式
/*
* 单例模式之懒汉式
* */
public class TeacherTest {
public static void main(String[] args){
Teacher t1 = Teacher.getTeacher();
Teacher t2 = Teacher.getTeacher();
System.out.println("t1="+t1);
System.out.println("t2="+t2);
System.out.println(t1 == t2);
}
}
public class Teacher {
// 私有化构造方法,不让外界创建对象
private Teacher(){
}
// 在成员变量位置声明变量(共享数据)
private static Teacher t = null;
// 提供公共的访问方法去获得Teacher对象
public static synchronized Teacher getTeacher(){ //同步方法,解决线程安全
// 判断当前该对象没有更多引用时,才创建对象
if(t == null){
t = new Teacher();
}
return t;
}
}
结果:
四、装饰者设计模式
1.概述:装饰者模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类(继承的替代方案)
// 定义被装饰者
public interface Phone {
public abstract void call();
}
// 定义装饰者
public abstract class PhoneDecorate implements Phone{
private Phone p ;
public PhoneDecorate(Phone p){
this.p = p ;
}
@Override
public void call() {
p.call() ;
}
}
// 具体的实现类
public class IPhone implements Phone {
@Override
public void call() {
System.out.println("手机打电话");
}
}
// 铃声功能
public class RingPhoneDecorate extends PhoneDecorate {
public RingPhoneDecorate(Phone p) {
super(p);
}
public void ringPhone(){
System.out.println("手机可以听彩铃");
}
@Override
public void call() {
ringPhone();
super.call();
}
}
// 音乐功能
public class MusicPhoneDecorate extends PhoneDecorate {
public MusicPhoneDecorate(Phone p) {
super(p);
}
public void musicPhone(){
System.out.println("手机可以听音乐");
}
@Override
public void call() {
super.call();
musicPhone();
}
}
// 测试类
public class PhoneTest {
public static void main(String[] args){
Phone p = new IPhone();
PhoneDecorate pd = new MusicPhoneDecorate(new RingPhoneDecorate(p));
pd.call();
}
}
结果: