文章目录
设计模式
设计原则
单一职责
- 一个方法只负责一件事情
开闭原则:
- 尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化
里氏替换原则
- 子类可以扩展父类的功能,但不能改变父类原有的功能。子类可以实现父类的抽象方
法,但不能覆盖父类的非抽象方法,子类中可以增加自己特有的方法
接口隔离原则
- 客户不应该依赖于它所不需要的接口,使用多个隔离的接口,比使用单个接口要好
迪米特法则(最少知道原则)
- 一个类尽量减少自己对其他对象的依赖
创建型模式
单例模式
- 饿汉模式(Early Instantiation of Singleton Pattern)
借助于JVM类加载机制,初始化阶段就完成了实例的初始化,保证实例的唯一性(初始化过程只会执行一次),线程安全(JVM以同步的方式完成类加载的整个过程)
public class Singleton {
private Singleton(){
}
private static final Singleton INSTANCE = new Singleton();
public static Singleton getInstance() {
return INSTANCE;
}
}
- 懒汉模式(Lazy Instantiation of Singleton Pattern)
public class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance() {
if(instance == null) {
synchronized (Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 静态内部类
结合了懒汉式和饿汉式各自的优点,真正需要对象的时候才会加载,加载类是线程
安全的。
/**
*通过静态内部类的方式懒加载获取线程安全的实例
*/
public class ResourceFactory {
private static class ResourceHolder{
public static ResourceFactory instance = new ResourceFactory();
}
public static ResourceFactory getResource() {
return ResourceHolder.instance;
}
}
工厂方法模式
工厂方法(Factory Method Pattern )
创建实例的职责交给子类
public abstract class Plan {
protected double rate;
abstract void getRate();
public void calculateBill(int unit) {
System.out.println(unit * rate);
}
}
class DomesticPlan extends Plan {
@Override
void getRate() {
rate = 3.50;
}
}
class CommercialPlan extends Plan {
@Override
void getRate() {
rate = 7.50;
}
}
class InstitutionalPlan extends Plan {
@Override
public void getRate() {
rate = 5.50;
}
}
public class GetPlanFactory {
public Plan getPlan(String planType) {
if (planType == null) {
return null;
}
if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
return new DomesticPlan();
} else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
return new CommercialPlan();
} else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
return new InstitutionalPlan();
}
return null;
}
public static void main(String args[]) throws IOException {
GetPlanFactory planFactory = new GetPlanFactory();
System.out.print("Enter the name of plan for which the bill will be generated: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String planName = br.readLine();
System.out.print("Enter the number of units for bill will be calculated: ");
int units = Integer.parseInt(br.readLine());
Plan p = planFactory.getPlan(planName);
System.out.print("Bill amount for " + planName + " of " + units + " units is: ");
p.getRate();
p.calculateBill(units);
}
}
抽象工厂方法(Abstract Factory Pattern)
在工厂方法的基础上,提供公共的抽象工厂类
public interface Bank {
String getBankName();
}
class HDFC implements Bank {
private final String BNAME;
public HDFC() {
BNAME = "HDFC BANK";
}
@Override
public String getBankName() {
return BNAME;
}
}
class ICICI implements Bank {
private final String BNAME;
public ICICI() {
BNAME = "ICICI BANK";
}
@Override
public String getBankName() {
return BNAME;
}
}
class SBI implements Bank {
private final String BNAME;
public SBI() {
BNAME = "SBI BANK";
}
@Override
public String getBankName() {
return BNAME;
}
}
abstract class Loan {
protected double rate;
abstract void getInterestRate(double rate);
public void calculateLoanPayment(double loanamount, int years) {
int n = years * 12;
rate = rate / 1200;
double EMI = ((rate * Math.pow((1 + rate), n)) / ((Math.pow((1 + rate), n)) - 1)) * loanamount;
System.out.println("your monthly EMI is " + EMI + " for the amount" + loanamount + " you have borrowed");
}
}
class HomeLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
}
class BussinessLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
}
class EducationLoan extends Loan {
public void getInterestRate(double r) {
rate = r;
}
}
/**
*定义抽象工厂
*/
public abstract class AbstractFactory {
public abstract Bank getBank(String bank);
public abstract Loan getLoan(String loan);
}
class BankFactory extends AbstractFactory {
public Bank getBank(String bank) {
if (bank == null) {
return null;
}
if (bank.equalsIgnoreCase("HDFC")) {
return new HDFC();
} else if (bank.equalsIgnoreCase("ICICI")) {
return new ICICI();
} else if (bank.equalsIgnoreCase("SBI")) {
return new SBI();
}
return null;
}
public Loan getLoan(String loan) {
return null;
}
}
class LoanFactory extends AbstractFactory {
public Bank getBank(String bank) {
return null;
}
public Loan getLoan(String loan) {
if (loan == null) {
return null;
}
if (loan.equalsIgnoreCase("Home")) {
return new HomeLoan();
} else if (loan.equalsIgnoreCase("Business")) {
return new BussinessLoan();
} else if (loan.equalsIgnoreCase("Education")) {
return new EducationLoan();
}
return null;
}
}
class FactoryCreator {
public static AbstractFactory getFactory(String choice) {
if (choice.equalsIgnoreCase("Bank")) {
return new BankFactory();
} else if (choice.equalsIgnoreCase("Loan")) {
return new LoanFactory();
}
return null;
}
public static void main(String args[]) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the name of Bank from where you want to take loan amount: ");
String bankName = br.readLine();
System.out.print("\n");
System.out.print("Enter the type of loan e.g. home loan or business loan or education loan : ");
String loanName = br.readLine();
AbstractFactory bankFactory = FactoryCreator.getFactory("Bank");
Bank b = bankFactory.getBank(bankName);
System.out.print("\n");
System.out.print("Enter the interest rate for " + b.getBankName() + ": ");
double rate = Double.parseDouble(br.readLine());
System.out.print("\n");
System.out.print("Enter the loan amount you want to take: ");
double loanAmount = Double.parseDouble(br.readLine());
System.out.print("\n");
System.out.print("Enter the number of years to pay your entire loan amount: ");
int years = Integer.parseInt(br.readLine());
System.out.print("\n");
System.out.println("you are taking the loan from " + b.getBankName());
AbstractFactory loanFactory = FactoryCreator.getFactory("Loan");
Loan l = loanFactory.getLoan(loanName);
l.getInterestRate(rate);
l.calculateLoanPayment(loanAmount, years);
}
}
建造者模式
- 当需要实例化一个复杂的类,以得到不同结构和不同内部状态对象时,我们可以使用不同的类对他们的实例化操作逻辑分别进行封装,这些类就被称为建造者。
package com.ljb;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
public class Settings {
private final Map<String,Object> settings;
private Settings(Map<String,Object> settings) {
this.settings = settings;
}
public static Builder builder() {
return new Builder();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(Entry<String, Object> entries : settings.entrySet()) {
sb.append(entries.getKey()).append(":").append(entries.getValue()).append("\n");
}
return sb.toString();
}
public static class Builder {
private final Map<String, Object> map = new TreeMap<>();
private Builder() {
}
public Builder put(String key,Object value) {
map.put(key, value);
return this;
}
public Settings build() {
return new Settings(map);
}
}
public static void main(String[] args) {
Settings settings = Settings.builder().put("com.ljb.name", "ljb").put("com.ljb.age", "18").build();
System.out.println(settings);
}
}
原型模式
- 当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
public class ProtoTypeTest {
private static Map<String, ProtoTypeTest> map = new ConcurrentHashMap<>();
private ProtoTypeTest() {
System.out.println("init");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread() {
public void run() {
System.out.println(getInstance());
}
}.start();
}
}
public static ProtoTypeTest getInstance() {
String key = "key";
return map.computeIfAbsent(key, k -> {
return new ProtoTypeTest();
});
}
}
行为型模式
责任链模式
- 责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将整个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
命令模式
- Command
public interface Command {
public abstract void execute();
}
- Command实现
public class ExitCommand implements Command {
private Receiver receiver;
public ExitCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.exitAction();
}
}
- Receiver
public class Receiver {
public void helpAction() {
System.out.println("help");
}
public void exitAction() {
System.out.println("exit");
}
}
- Invoker
public class Invoker {
private Command cmd;
public Invoker(Command cmd) {
this.cmd = cmd;
}
public void call() {
cmd.execute();
}
}
- Client
public class Client {
public static void main(String[] args) {
Receiver receiver = new Receiver();
new Invoker(new HelpCommond(receiver)).call();
new Invoker(new ExitCommand(receiver)).call();
}
}
解释器模式
迭代模式
观察者模式
- 参考谷歌的guava,JDK 的观察者实现方式
中介者模式
备忘录模式
状态模式
策略模式
- 改变解决一个问题与另一个问题的方式
模板方法模式
- 本意就是抽取公共的方法
空对象模式
访问者模式
结构型模式
适配器模式
public class Adaptee {
public void add() {
}
public void remove() {
}
}
class Adapter extends Adaptee{
@Override
public void add() {
throw new RuntimeException("not support");
}
@Override
public void remove() {
super.remove();
}
}
代理模式
It provides the protection to the original object from the outside world.
A访问C通过中间人B
装饰器模式
- 动态扩展现有的对象而不是更改原有的代码,能够适配原始接口,并且使用组合二不是子类化来扩展功能
桥接模式
- 将功能抽象与实现分离,以便两者可以独立变化
public interface Question {
public abstract void nextQuestion();
public abstract void previousQuestion();
public abstract void newQuestion(String q);
public abstract void deleteQuestion(String q);
public abstract void displayQuestion();
public abstract void displayAllQuestions();
}
class JavaQuestions implements Question {
private List<String> questions = new ArrayList<String>();
private int current = 0;
public JavaQuestions() {
questions.add("What is class? ");
questions.add("What is interface? ");
questions.add("What is abstraction? ");
questions.add("How multiple polymorphism is achieved in java? ");
questions.add("How many types of exception handling are there in java? ");
questions.add("Define the keyword final for variable, method, and class in java? ");
questions.add("What is abstract class? ");
questions.add("What is multi-threading? ");
}
public void nextQuestion() {
if (current <= questions.size() - 1)
current++;
System.out.print(current);
}
public void previousQuestion() {
if (current > 0)
current--;
}
public void newQuestion(String quest) {
questions.add(quest);
}
public void deleteQuestion(String quest) {
questions.remove(quest);
}
public void displayQuestion() {
System.out.println(questions.get(current));
}
public void displayAllQuestions() {
for (String quest : questions) {
System.out.println(quest);
}
}
}
/**
*act as a bridge
*/
class QuestionManager {
protected Question q;
public String catalog;
public QuestionManager(String catalog) {
this.catalog = catalog;
}
public void next() {
q.nextQuestion();
}
public void previous() {
q.previousQuestion();
}
public void newOne(String quest) {
q.newQuestion(quest);
}
public void delete(String quest) {
q.deleteQuestion(quest);
}
public void display() {
q.displayQuestion();
}
public void displayAll() {
System.out.println("Question Paper: " + catalog);
q.displayAllQuestions();
}
}
class QuestionFormat extends QuestionManager {
public QuestionFormat(String catalog){
super(catalog);
}
public void displayAll() {
System.out.println("\n---------------------------------------------------------");
super.displayAll();
System.out.println("-----------------------------------------------------------");
}
}
public class BridgePatternDemo {
public static void main(String[] args) {
QuestionFormat questions = new QuestionFormat("Java Programming Language");
questions.q = new JavaQuestions();
questions.delete("what is class?");
questions.display();
questions.newOne("What is inheritance? ");
questions.newOne("How many types of inheritance are there in java?");
questions.displayAll();
}
}
组合模式
外观模式
亨元模式
- 参考Boolean.valueOf(boolean b);