標簽(空格分隔): android
設計模式六大原則
- 單一職責原則:就一個類來說昼扛,應該僅有一個引起他變化的原因瞭恰。
- 開源封閉原則:類弛随、模板瓢喉、函數(shù)等應該可以拓展,但不可修改舀透。
- 里氏替換原則:所有引用基類的地方必須透明地使用其子類的對象栓票。
- 依賴倒置的原則:高層模塊不應該依賴低層模塊,兩者都應該依賴于抽象盐杂,抽象不應該依賴于細節(jié)逗载,細節(jié)應該依賴于抽象。
- 迪米特原則:一個軟件實體應當盡可能少地與其他實體發(fā)生相互作用链烈。
- 接口隔離原則:一個類對另一個類的依賴應建立在一個最小的接口厉斟。
單例模式
(1)餓漢模式
public class Sington{
private static Sington sington = new Sington();
private Sington(){
}
public static Sington getInstance(){
return sington;
}
}
(2)懶漢模式
//懶漢模式(線程不安全)
public class Sington{
private static Sington sington;
private Sington(){
}
public static Sington getInstance(){
if(sington == null){
sington = new Sington();
}
return sington;
}
}
//懶漢模式(線程安全)
public class Sington{
private static Sington sington;
private Sington(){
}
public static synchronized Sington getInstance(){
if(sington == null){
sington = new Sington();
}
return sington;
}
}
(3)雙重檢查模式(DCL)
//雙重檢查模式
public class DCL {
private static volatile DCL dcl;
private DCL(){};
public static DCL getInstance(){
if(dcl == null){
synchronized (DCL.class){
if(dcl == null){
dcl = new DCL();
}
}
}
return dcl;
}
}
(4)靜態(tài)內(nèi)部類單例模式和枚舉單例模式
/靜態(tài)內(nèi)部類單例模式
public class StaicSington {
private StaicSington(){
}
public static StaicSington getInstance(){
return SingletonHolder.singleton;
}
private static class SingletonHolder{
private static final StaicSington singleton = new StaicSington();
}
}
//枚舉單例,線程安全
enum Singleton{
INSTANCE;
public void doSomeThing(){
}
}
簡單工廠模式
定義:屬于建造型模式强衡,又一個工廠對象創(chuàng)建出哪一種產(chǎn)品類實例擦秽。
//調(diào)用
public class Simple {
public static void main(String[] args){
ComputerFactory.createComputer("hp").start();
}
}
//抽象產(chǎn)品類
abstract class Computer{
public abstract void start();
}
//具體產(chǎn)品類
class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("Lenovo電腦");
}
}
class HPComputer extends Computer{
@Override
public void start() {
System.out.println("hp電腦");
}
}
//工廠類
class ComputerFactory{
public static Computer createComputer(String type){
Computer computer = null;
switch (type){
case "lenovo":
computer = new LenovoComputer();
break;
case "hp":
computer = new HPComputer();
break;
default:
break;
}
return computer;
}
}
優(yōu)點:避免直接實例化類,降低耦合性漩勤。
缺點:實例化對象在編譯階段就已經(jīng)確定感挥,添加新類型,需要修改工廠越败,這不符合開放封閉原則触幼。
工廠方法模式
定義:定義一個用于創(chuàng)建對象接口,讓子類決定實例化哪一個類究飞,工廠方法讓一個類的實例化延遲到他的子類置谦。
//調(diào)用
public class Simple {
public static void main(String[] args){
ComputerFactory computerFactory =new GDComputerFactory();
LenovoComputer lenovoComputer = computerFactory.createCompter(LenovoComputer.class);
lenovoComputer.start();
HPComputer hpComputer = computerFactory.createCompter(HPComputer.class);
hpComputer.start();
}
}
//抽象產(chǎn)品類
abstract class Computer{
public abstract void start();
}
//具體產(chǎn)品類
class LenovoComputer extends Computer{
@Override
public void start() {
System.out.println("Lenovo電腦");
}
}
class HPComputer extends Computer{
@Override
public void start() {
System.out.println("hp電腦");
}
}
abstract class ComputerFactory{
public abstract <T extends Computer> T createCompter(Class<T> tClass);
}
//運用反射的知識
class GDComputerFactory extends ComputerFactory{
@Override
public <T extends Computer> T createCompter(Class<T> tClass) {
Computer computer = null;
String className = tClass.getName();
try{
computer = (Computer) Class.forName(className).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return (T)computer;
}
}
建造者模式
定義:將一個復雜對象的構(gòu)建和它的表示分離,使得同樣的構(gòu)建過程可以建造不同的表示亿傅。
public class BuilderUse {
public static void main(String[] args){
Builder mbuilder = new MoonComputerBuilder();
Director director = new Director(mbuilder);
director.CreateCompter("i7","haha","三星DDr4");
}
}
class ComputerOne{
private String cpu;
private String mainboard;
private String ram;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
public void setRam(String ram) {
this.ram = ram;
}
}
//抽象的建造者
abstract class Builder{
public abstract void buildeCpu(String cpu);
public abstract void bulidMainboard(String mainboard);
public abstract void buildRam(String ram);
public abstract ComputerOne create();
}
class MoonComputerBuilder extends Builder{
private ComputerOne computer = new ComputerOne();
@Override
public void buildeCpu(String cpu) {
computer.setCpu(cpu);
}
@Override
public void bulidMainboard(String mainboard) {
computer.setMainboard(mainboard);
}
@Override
public void buildRam(String ram) {
computer.setRam(ram);
}
@Override
public ComputerOne create() {
return computer;
}
}
class Director{
Builder builder = null;
public Director(Builder builder){
this.builder = builder;
}
public ComputerOne CreateCompter(String cpu,String mainboard,String ram){
this.builder.buildeCpu(cpu);
this.builder.buildRam(ram);
this.builder.bulidMainboard(mainboard);
return builder.create();
}
}
優(yōu)點:客戶端不必知道產(chǎn)品內(nèi)部細節(jié)媒峡,構(gòu)建者類相互獨立,易于拓展葵擎。
缺點:產(chǎn)生了多余的對象Build對象和Director對象谅阿。
代理模式
定義:為其他對象提供一種代理以控制對這個對象的訪問。
//抽象主題類
public interface IUser {
void save();
void get();
}
//實際主題類
public class User implements IUser {
public void save(){
System.out.println("User類調(diào)用");
}
@Override
public void get() {
System.out.println("User類調(diào)用---get");
}
}
//靜態(tài)代理
public class UserProxy implements IUser {
private IUser target;
public UserProxy(IUser target){
this.target = target;
}
public void save(){
System.out.println("開始代理類");
target.save();
System.out.println("提交事務酬滤。签餐。。");
}
@Override
public void get() {
}
}
//動態(tài)代理
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
public Object getProxyInstance(){
//使用反射的知識
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("開始ProxyFactory");
Object value = method.invoke(target,args);
System.out.println("開始二");
return value;
}
});
}
}
優(yōu)點:真實主題類只用關(guān)注實際的邏輯業(yè)務盯串,而無需關(guān)注非本職工作贱田。
裝飾模式
定義:動態(tài)地給一個對象添加額外的職責,裝飾模式比生成子類更加靈活嘴脾。
public class Decoration {
public static void main(String[] args){
YangGuo yangGuo = new YangGuo();
HongQiGong hongQiGong = new HongQiGong(yangGuo);
hongQiGong.attackMagic();
}
}
//抽象組件
abstract class Swordsman{
abstract void attackMagic();
}
//組件具體的實現(xiàn)類
class YangGuo extends Swordsman{
@Override
void attackMagic() {
System.out.println("楊過使用全真劍法");
}
}
//抽象裝飾者
abstract class Master extends Swordsman{
private Swordsman swordsman;
public Master(Swordsman swordsman){
this.swordsman = swordsman;
}
@Override
void attackMagic() {
swordsman.attackMagic();
}
}
//裝飾者具體實現(xiàn)類
class HongQiGong extends Master{
@Override
void attackMagic() {
super.attackMagic();
teachAttackMagic();
}
public HongQiGong(Swordsman swordsman) {
super(swordsman);
}
public void teachAttackMagic(){
System.out.println("洪七公打狗棒");
System.out.println("楊過使用打狗棒");
}
}
優(yōu)點:符合開放封閉原則,擴展靈活性。
缺點:易出錯译打,裝飾層次不能修飾層數(shù)過多耗拓,否則影響效率。
外觀模式
定義:要求一個子系統(tǒng)的外部與內(nèi)部通信必須通過一個統(tǒng)一的對象進行奏司,此模式下提供一個高層接口乔询,使得子系統(tǒng)便于使用。
簡單實例:
//客戶端調(diào)用
public class OutSee {
public static void main(String[] args){
Man man = new Man();
//這個人使用降魔掌和太極拳
man.TaiJiQuan();
man.XiangMoZhang();
}
}
//子系統(tǒng)
class ZhaoShi{
public void TaiJiQuan(){
System.out.println("使用招式太極拳");
}
public void QiShangQuan(){
System.out.println("使用七傷拳");
}
public void XiangMoZhang(){
System.out.println("使用降魔掌");
}
}
//子系統(tǒng)
class LeiGong{
public void JiuYing(){
System.out.println("使用九陰真經(jīng)");
}
public void JiuYang(){
System.out.println("使用九陽神功");
}
}
//外觀類
class Man{
private ZhaoShi zhaoShi;
private LeiGong leiGong;
public Man(){
zhaoShi = new ZhaoShi();
leiGong = new LeiGong();
}
//使用太極拳先使用九陽神功
public void TaiJiQuan(){
leiGong.JiuYang();
zhaoShi.TaiJiQuan();
}
//使用降魔掌必須先使用九陰神功
public void XiangMoZhang(){
leiGong.JiuYing();
zhaoShi.XiangMoZhang();
}
}
優(yōu)點:減少相互依賴韵洋,降低耦合性竿刁,加強了安全性。
缺點:不符合開放原則搪缨。
享元模式
定義:使用共享對象有效地支持大量細粒度對象食拜。
//客戶端調(diào)用
public class ShareYuan {
public static void main(String[] args){
Goods goods1 = GoodsFactory.getGoods("oneplus7");
goods1.showGoodPrice("32g");
Goods goods2 = GoodsFactory.getGoods("oneplus7");
goods1.showGoodPrice("32g");
Goods goods3 = GoodsFactory.getGoods("oneplus7");
goods1.showGoodPrice("128g");
}
}
//抽象的享元角色
interface IGoods{
public void showGoodPrice(String version);
}
//具體的享元對象
class Goods implements IGoods{
private String name;
private String version;
Goods(String name){
this.name = name;
}
@Override
public void showGoodPrice(String version) {
if(version.equals("32g")){
System.out.println("價格為2365");
}else if(version.equals("128g")){
System.out.println("價格為5999");
}
}
}
//享元工廠
class GoodsFactory{
private static Map<String,Goods> pool = new HashMap<>();
public static Goods getGoods(String name){
if(pool.containsKey(name)){
System.out.println("使用緩存,key為"+name);
return pool.get(name);
}else {
Goods goods = new Goods(name);
pool.put(name,goods);
System.out.println("創(chuàng)建商品副编,key為"+name);
return goods;
}
}
}
使用場景:
- 系統(tǒng)中有大量相似對象负甸。
- 需要緩存池。
策略模式
定義:定義一系列的算法痹届,把每一個算法封裝起來呻待,而且使它們可以相互轉(zhuǎn)換。策略模式獨立于使用它的用戶队腐。
簡單實例:
public class Concrete {
public static void main(String args[]){
Context context;
context = new Context(new WeakRivalStrategy());
context.fighting();
context = new Context(new CommonRiverStrategy());
context.fighting();
}
}
//定義策略接口
interface FightingStrategy{
public void fighting();
}
//具體策略實現(xiàn)
class WeakRivalStrategy implements FightingStrategy{
@Override
public void fighting() {
System.out.println("遇到較弱的對手");
}
}
class CommonRiverStrategy implements FightingStrategy{
@Override
public void fighting() {
System.out.println("遇到普通對手");
}
}
//上下文對象
class Context{
private FightingStrategy fightingStrategy;
public Context(FightingStrategy fightingStrategy){
this.fightingStrategy = fightingStrategy;
}
public void fighting(){
fightingStrategy.fighting();
}
}
優(yōu)點:可以避免使用多重條件語句蚕捉,易于擴展。
缺點:每個策略類都是一個類柴淘,復用性衅妊汀;和迪米特原則違背悠就。
觀察者模式
定義:定義對象間一種一對多的依賴關(guān)系千绪,每當一個對象改變狀態(tài)時,則所有依賴于它的對象都會得到通知并被自動更新梗脾。
public class ObserveDo {
public static void main(String args[]){
SubscriptionSubject subscriptionSubject = new SubscriptionSubject();
WeixinUser user1 = new WeixinUser("jake");
WeixinUser user2 = new WeixinUser("tom");
WeixinUser user3 = new WeixinUser("herry");
subscriptionSubject.attach(user1);
subscriptionSubject.attach(user2);
subscriptionSubject.attach(user3);
subscriptionSubject.notify("hahahahahaa");
}
}
//抽象觀察者
interface Observer{
public void update(String message);
}
//具體的觀察者
class WeixinUser implements Observer{
private String name;
public WeixinUser(String name){
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name+"-"+message);
}
}
//抽象被觀察者
interface Subject{
public void attach(Observer observer);
public void detach(Observer observer);
public void notify(String message);
}
//具體被觀察者
class SubscriptionSubject implements Subject{
private List<Observer> observeDos = new ArrayList<>();
@Override
public void attach(Observer observer) {
observeDos.add(observer);
}
@Override
public void detach(Observer observer) {
observeDos.remove(observer);
}
@Override
public void notify(String message) {
for(Observer observer : observeDos){
observer.update(message);
}
}
}
優(yōu)點:觀察者和被觀察者之間抽象耦合荸型,容易拓展。
缺點:開發(fā)效率低下炸茧。