Java程序设计六大原则&设计模式

Java程序设计六大原则

一、单一职责原则:

一个接口或者类只有一个原因引起变化,即一个接口或者类只有一个职责,负责一件事情。(此原则同样适用于方法)

好处:1、复杂性降低;2、可读性提高;3、可维护性提高;4、变更风险降低

二、里氏替换原则:

父类能出现的地方子类就可以出现
定义解释:
1、子类必须完全实现父类的方法;

2、子类可以有自己的个性;

3、覆盖或者实现父类的方法时,输入参数可以被放大;

public class Father {undefined
    public Collection doSomething(HashMap map) {undefined
        System.out.println("父类被执行了");
        return map.values();
    }
}

public class Son extends Father {undefined
    public Collection  doSomething(Map  map) {undefined
        System.out.println("子类被执行了");
        return map.values();
    }    
}

public static void main(String[] args) {undefined
    Father father = new Father();
    Son son = new Son();
    HashMap map = new HashMap<>();
    
    father.doSomething(map);
    son.doSomething(map);
}

以上代码执行时,子类重载了父类的doSomething方法,并且放大输入参数Hashmap→Map,执行以后,出现相同的结果,均输出"父类被执行了",并没有歪曲父类的意图,不会引起业务逻辑混乱,符合里氏替换原则。

4、覆写或者实现父类的方法时,输出结果可以被缩小;

三、依赖倒置原则:

1、高层不应该依赖底层,两者都应该依赖其抽象;

2、抽象不应该依赖细节,细节应该依赖抽象;
即模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的。更加简单的定义就是"面向接口编程(OOD:Object-Oriented Design)"

四、接口隔离原则:

通俗的讲,接口尽量细化,同时接口中的方法尽量少。说明:单一职责原则侧重于业务逻辑,即职责尽量少;而接口隔离原则侧重于接口中的方法尽量少。

五、迪米特法则:

也称为最少知识原则:一个对象应该对其他对象有最少的了解。通俗的讲:一个类应该对自己需要耦合或者调用的类知道的越少越好

六、开闭原则:

软件实体应该对扩展开放,对修改关闭。就是说应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

设计模式:

一、门面模式(外观模式):

是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。

定义一个(或多个)具备所需接口的新类(门面类);
新类门户使用原来的系统;
客户使用门面类对象与原系统打交道;

1、activity内部直接使用三方网络请求库的api 来请求网络,导致activity和网络请求库高度耦合,且违背单一职责原则。

2、使用门面模式对网络请求框架进行封装,使用单例模式编写门面类,在门面类内部直接使用三方网络请求库的api 来请求网络(即门面类拥有网络库的功能),并定义网络返回结果的接口,最后通过接口回调的方式返回网络请求结果到activity。

// 接口
public interface IHttpApi {

    void register();

    void login();

    void getUserInfo();
}

// 三方网络库
public class OkHttp implements IHttpApi {
    @Override
    public void register() {
        System.out.println("OkHttp register");
    }

    @Override
    public void login() {
        System.out.println("OkHttp login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("OkHttp getUserInfo");
    }
}


// 门面类
public class UserApi {

    private OkHttp okHttp;

    public static UserApi getInstance(){
        return UserApiHelper.userApi;
    }

    private static class UserApiHelper{
        private static UserApi userApi = new UserApi();
    }

    private UserApi() {
        okHttp = new OkHttp();
    }

    public void login(){
        System.out.println("UserApi login");
        okHttp.register();
        okHttp.login();
    }

    public void getUserInfo(){
        System.out.println("UserApi getUserInfo");
        okHttp.login();
        okHttp.getUserInfo();
    }
}

// 使用
public static void main(String[] args) {
        UserApi.getInstance().login();
        UserApi.getInstance().getUserInfo();
    }

Java程序设计六大原则&设计模式_第1张图片

优点:解耦activity和三方网络库,activity实现单一职责原则;

缺点:门面类和网络请求库高度耦合,当需要切换网络库时,需要修改整个门面类,违背了开闭原则。

二、代理模式(Proxy):

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

1、创建代理类,三方库实现类,统一规则接口;

public interface IHttpApi {

    void register();

    void login();

    void getUserInfo();
}

2、代理类和三方库都要实现统一规则接口,同时代理类拥有三方库实现类这个对象(以接口的形式持有)

// 三方库OkHttp 
public class OkHttp implements IHttpApi {
    @Override
    public void register() {
        System.out.println("OkHttp register");
    }

    @Override
    public void login() {
        System.out.println("OkHttp login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("OkHttp getUserInfo");
    }
}

// 三方库Volley 
public class Volley implements IHttpApi {
    @Override
    public void register() {
        System.out.println("Volley register");
    }

    @Override
    public void login() {
        System.out.println("Volley login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("Volley getUserInfo");
    }
}

// 代理类
public class UserApi implements IHttpApi {
    private IHttpApi iHttpApi;

    public UserApi(IHttpApi iHttpApi) {
        this.iHttpApi = iHttpApi;
    }


    @Override
    public void register() {
        System.out.println("UserApi register");
        iHttpApi.register();
    }

    @Override
    public void login() {
        System.out.println("UserApi login");
        iHttpApi.login();
    }

    @Override
    public void getUserInfo() {
        System.out.println("UserApi getUserInfo");
        iHttpApi.getUserInfo();
    }
}

3、三方库实现类,直接使用三方网络请求库的api 来请求网络(即三方库实现类拥有网络库的功能)

4、统一规则接口,即get和post方法

5、在初始代理类时,需要传入三方库实现类的类型(如:volley或okhttp)。

6、用户调用代理类实现的网络请求接口时,代理类通过调用 持有的三方库实现类 去调用三方网络请求库的api 来请求网络。

7、代理类本身不具备网络库的功能,充当中介的作用,去调用三方库实现类。

public static void main(String[] args) {
        // 代理OkHttp
        System.out.println("代理OkHttp");
        OkHttp okHttp = new OkHttp();
        UserApi userApi = new UserApi(okHttp);
        userApi.register();
        userApi.login();
        userApi.getUserInfo();
        // 代理Volley
        System.out.println("代理Volley");
        Volley volley = new Volley();
        userApi = new UserApi(volley);
        userApi.register();
        userApi.login();
        userApi.getUserInfo();
    }

Java程序设计六大原则&设计模式_第2张图片

优点:解耦代理类和三方网络库,当需要更换三方网络库时,直接在初始化代理类时,需要传入新的三方库实现类。

三方库实现类使用了里氏替换原则,子类必须完全实现父类的方法。

三、单例模式:

确保一个类只有一个实例,而且自行实例化并向整个系统或应用提供这个实例。

饿汉模式
懒汉模式
Double Check Lock
枚举单例
静态内部类实现单例(最优雅单例)

private static class SingletonHolder {
    private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getSingleton5() {
    return SingletonHolder.INSTANCE;
}

四、建造者模式(Builder模式):

将一个复杂对象的创建和表示分离,使用相同的构建过程创建不同的对象。

public class TestPerson {
    private String mPersonName;
    private int mPersonAge;
    private int mSex;
    private String mCardNumber;

    public TestPerson TestPerson(){
        return new TestPerson(new TestPerson.Builder());
    }

    public TestPerson(TestPerson.Builder builder){
        this.mCardNumber = builder.mCardNumber;
        this.mSex = builder.mSex;
        this.mPersonAge = builder.mPersonAge;
        this.mPersonName = builder.mPersonName;
    }

    public static final class Builder {
        private String mPersonName;
        private int mPersonAge;
        private int mSex;
        private String mCardNumber;

        public Builder(){}

        public TestPerson build(){
            return new TestPerson(this);
        }

        public TestPerson.Builder addPersonName(String mPersonName) {
            this.mPersonName = mPersonName;
            return this;
        }

        public TestPerson.Builder addPersonAge(int mPersonAge) {
            this.mPersonAge = mPersonAge;
            return this;
        }

        public TestPerson.Builder addSex(int mSex) {
            this.mSex = mSex;
            return this;
        }

        public TestPerson.Builder addCardNumber(String mCardNumber) {
            this.mCardNumber = mCardNumber;
            return this;
        }
    }
}

TestPerson pserson = new TestPerson.Builder()
        .addPersonName("狗蛋")
        .addSex(1)
        .addPersonAge(18)
        .build();

五、观察者模式(Observer Pattern):

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

三要素:Observer是观察者接口,Observable是被观察者接口,ObservableImpl是被观察者实现类(管理所有观察者)。

Observer观察者接口:

public interface Observer {
    void update(String message);
}

Observable被观察者接口:

public interface Observable {
    // 添加观察者
    void addObserver(Observer observer);

    // 移除观察者
    void removeObserver(Observer observer);

    // 通知观察者
    void notifyObserver(String message);
}

ObservableImpl被观察者实现类:

public class ObservableImpl implements Observable {

    private List observerList = new ArrayList<>();

    public static ObservableImpl getInstance() {
        return ObservableHelper.observable;
    }

    private static class ObservableHelper {
        private static ObservableImpl observable = new ObservableImpl();
    }

    @Override
    public void addObserver(Observer observer) {
        if (!observerList.contains(observer)) {
            observerList.add(observer);
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        if (observerList.contains(observer)) {
            observerList.remove(observer);
        }
    }

    @Override
    public void notifyObserver(String message) {
        for (Observer observer : observerList) {
            observer.update(message);
        }
    }
}

ObserverImpl观察者实现类:

public class ObserverImpl implements Observer {

    private String observerName;

    public ObserverImpl(String observerName) {
        this.observerName = observerName;
    }

    @Override
    public void update(String message) {
        System.out.println(observerName + ":" + message);
    }
}

ObserverImpl观察者实现类,一般不需要单独编写实现类,这里是为了测试;比如:view要观察activity数据变化而刷新UI,view只要实现Observer观察者接口,view就是观察者实现类。

public static void main(String[] args) {
        // 创建观察者
        ObserverImpl observer1 = new ObserverImpl("observer1");
        ObserverImpl observer2 = new ObserverImpl("observer2");
        ObserverImpl observer3 = new ObserverImpl("observer3");
        // 添加观察者
        ObservableImpl.getInstance().addObserver(observer1);
        ObservableImpl.getInstance().addObserver(observer2);
        ObservableImpl.getInstance().addObserver(observer3);
        // 通知观察者
        ObservableImpl.getInstance().notifyObserver("更新数据");
    }

Java程序设计六大原则&设计模式_第3张图片

六、工厂模式:

定义一个用于创建对象的接口,让子类决定实例化哪个类。

创建一个接口:

public interface Car {
    void drive();
}

创建实现接口的实体类:

// 自行车
public class Bike implements Car{
    @Override
    public void drive() {
        System.out.println("Bike drive");
    }
}


// 大巴
public class Bus implements Car{
    @Override
    public void drive() {
        System.out.println("Bus drive");
    }
}

// 火车
public class Train implements Car {
    @Override
    public void drive() {
        System.out.println("Train drive");
    }
}

创建一个工厂,生成基于给定信息的实体类的对象:

public class CarFactory {
    public static Car makeCar(String type) {
        Car car = null;
        switch (type) {
            case "Bike":
                car = new Bike();
                break;
            case "Bus":
                car = new Bus();
                break;
            case "Train":
                car = new Train();
                break;
        }
        return car;
    }
}

使用该工厂,通过传递类型信息来获取实体类的对象。

public static void main(String[] args) {
        CarFactory.makeCar("Bike").drive();
        CarFactory.makeCar("Bus").drive();
        CarFactory.makeCar("Train").drive();
    }

Java程序设计六大原则&设计模式_第4张图片

七、策略模式:

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,策略模式让算法独立于使用它的客户而独立变化。

  • 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
  • 需要安全地封装多种同一类型的操作时;
  • 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。

使用场景:RecyclerView.ViewHolder,一个新闻列表页面,根据不同的viewtype需要分别显示左文右图和左图右文的效果;

创建一个接口,这里使用RecyclerView.ViewHolder

public abstract static class ViewHolder {
        // ...
}

创建实现接口的实体类

static class ViewHolder extends RecyclerView.ViewHolder {
	private ImageView ivIcon;
	private TextView tvZhName;
	private TextView tvEnName;

	public ViewHolder(View view) {
		super(view);
		ivIcon = view.findViewById(R.id.iv_icon);
		tvZhName = view.findViewById(R.id.tv_zh_name);
		tvEnName = view.findViewById(R.id.tv_en_name);
	}
}

根据不同的viewtype创建不同策略(布局)的ViewHolder

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
	View view = null;
	if (viewType == 15 || viewType == 16 || viewType == 17) {
		view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_long, parent, false);
	} else {
		view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_control, parent, false);
	}
	ViewHolder holder = new ViewHolder(view);
	return holder;
}

八、责任链模式:

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

你可能感兴趣的:(android,java,java,设计模式,servlet)