1、概述
2、面向对象设计原则
1)单一职责原则
2)开闭原则
3)里氏替换原则
4)依赖倒置原则
6)迪米特原则
7)组合/聚合复用原则
3、设计模式
4、设计模式分类
5、简单工厂模式
样例:
产品接口类(Product):
package com.ljb.simplefactory; /** * 产品接口 * @author LJB * @version 2015年4月21日 */ public interface Product { /**产品生产工艺*/ public void craftwork(); /**产品特征*/ public void type(); }
产品类(鲜奶):
package com.ljb.simplefactory; /** * 鲜奶 * @author LJB * @version 2015年4月21日 */ public class Creamery implements Product { @Override public void craftwork() { System.out.println("牛奶+除菌=鲜奶"); } @Override public void type() { System.out.println("原味浓香"); } }
产品类(酸奶):
package com.ljb.simplefactory; /** * 酸奶 * @author LJB * @version 2015年4月21日 */ public class Yoghourt implements Product { @Override public void craftwork() { System.out.println("牛奶+酵母菌+糖=酸奶"); } @Override public void type() { System.out.println("酸甜可口"); } }
简单工厂类:
package com.ljb.simplefactory; /** * 静态工厂 * @author LJB * @version 2015年4月21日 */ public class StaticFactory { public static Product factory (String str) throws BadException { if (str.equalsIgnoreCase("creamery")) { System.out.println("生产鲜奶"); return new Creamery(); } else if (str.equalsIgnoreCase("yoghourt")) { System.out.println("生产酸奶"); return new Yoghourt(); } else { throw new BadException("没有此产品"); } } }
异常类:
package com.ljb.simplefactory; /** * 自定义异常类 * @author LJB * @version 2015年4月21日 */ public class BadException extends Exception { public BadException (String msg) { super(msg); } }
测试类:
package com.ljb.simplefactory; /** * 测试类 * @author LJB * @version 2015年4月21日 */ public class Test { /** * @param args */ public static void main(String[] args) { try { Product x = StaticFactory.factory("creamery"); x.craftwork(); x.type(); Product y = StaticFactory.factory("yoghourt"); y.craftwork(); y.type(); } catch (BadException e) { e.printStackTrace(); } } }
执行结果:
生产鲜奶
牛奶+除菌=鲜奶
原味浓香
生产酸奶
牛奶+酵母菌+糖=酸奶
酸甜可口
小结:
工厂需要知道多有产品
缺点:对开闭原则支持不够
6、工厂方法模式
注:引入简单工厂模式中的产品接口及产品类
增加:
工厂接口(ProductFactory):
package com.ljb.factorymethod; /** * 工厂接口类 * @author LJB * @version 2015年4月21日 */ public interface ProductFactory { public Product factory(); }
工厂实现类(鲜奶工厂):
package com.ljb.factorymethod; /** * 鲜奶工厂 * @author LJB * @version 2015年4月21日 */ public class CreameryFactory implements ProductFactory { @Override public Product factory() { System.out.println("生产鲜奶"); return new Creamery(); } }
工厂实现类(酸奶工厂):
package com.ljb.factorymethod; /** * 酸奶工厂类 * @author LJB * @version 2015年4月21日 */ public class YoghourtFactory implements ProductFactory { @Override public Product factory() { System.out.println("生产酸奶"); return new Yoghourt(); } }
测试类:
package com.ljb.factorymethod; /** * 测试类 * @author LJB * @version 2015年4月21日 */ public class Test { /** * @param args */ public static void main(String[] args) { ProductFactory y = new CreameryFactory(); y.factory().craftwork(); y.factory().type(); ProductFactory x = new YoghourtFactory(); x.factory().craftwork(); x.factory().type(); } }
7、代理模式
样例:
抽象主题:
package com.ljb.proxy; /** * 抽象主题或者是接口 * @author LJB * @version 2015年4月21日 */ public abstract class Subject { /** * 声明一个抽象的请求方法 */ abstract public void request(); }
真实主题:
package com.ljb.proxy; /** * 真是主题 * @author LJB * @version 2015年4月21日 */ public class RealSubject extends Subject { @Override public void request() { System.out.println("实现请求"); } }
代理主题:
package com.ljb.proxy; /** * 代理主题(通过代理实现对真实主题的引用,并且可以加入自己的方法) * @author LJB * @version 2015年4月21日 */ public class ProxySubject extends Subject { private RealSubject realSubject; @Override public void request() { preRequest(); if (realSubject == null) { realSubject = new RealSubject(); } realSubject.request(); aftRequest(); } public void preRequest() { System.out.println("请求前的方法"); } public void aftRequest () { System.out.println("请求后的方法"); } }
测试类:
package com.ljb.proxy; /** * 测试类 * @author LJB * @version 2015年4月21日 */ public class Test { /** * @param args */ public static void main(String[] args) { Subject proxy = new ProxySubject(); proxy.request(); } }
运行结果:
请求前的方法
实现请求
请求后的方法
8、策略(strategy)模式
样例:
策略抽象类(抽象账户):
package com.ljb.strategy; /** * 抽象账户 * @author LJB * @version 2015年4月21日 */ public abstract class Account { /** * 计算产品的真实价格 * @param amount * @param price * @return */ public abstract float getFactPrice (int amount , int price); }
策略实现类(普通账户):
package com.ljb.strategy; /** * 普通客户商品价格计算类 * @author LJB * @version 2015年4月21日 */ public class CommonAccount extends Account { @Override public float getFactPrice(int amount, int price) { return amount*price; } }
策略实现类(会员账户):
package com.ljb.strategy; /** * 会员商品价格计算类 * @author LJB * @version 2015年4月21日 */ public class InsiderAccount extends Account { @Override public float getFactPrice(int amount, int price) { // TODO Auto-generated method stub return amount*price*9/10; } }
策略实现类(VIP账户):
package com.ljb.strategy; /** * vip会员商品价格计算类 * @author LJB * @version 2015年4月21日 */ public class VipAccount extends Account { @Override public float getFactPrice(int amount, int price) { // TODO Auto-generated method stub return amount*price*8/10; } }
策略维护类:
package com.ljb.strategy; /** * 此类用于维护策略类的引用 * 各个算法封装起来,通过维护类实现对各个算法的引用 * @author LJB * @version 2015年4月21日 */ public class Context { /**持有策略类的引用*/ private Account account; /** * 构造方法,实例化策略类的引用 * 父类作为方法形参的使用方式 * @param account */ public Context (Account account) { this.account = account; } /** * 调用策略方法 * @param amount * @param price * @return */ public float doAccount (int amount , int price) { return account.getFactPrice(amount, price); } }
测试类:
package com.ljb.strategy; /** * 测试类 * @author LJB * @version 2015年4月21日 */ public class Test { /** * @param args */ public static void main(String[] args) { String name = "CD唱片"; int amount = 2; int price = 50; float sum = 0; // 普通客户 Context common = new Context(new CommonAccount()); sum = common.doAccount(amount, price); System.out.println("您是普通客户没有折扣,商品名称:" + name + "数量:" + amount + "价格:" + price + "应付金额:" + sum); // 会员客户 Context insider = new Context(new InsiderAccount()); sum = insider.doAccount(amount, price); System.out.println("您是会员享受9折优惠,商品名称:" + name + "数量:" + amount + "价格:" + price + "应付金额:" + sum); // VIP客户 Context vip = new Context(new VipAccount()); sum = vip.doAccount(amount, price); System.out.println("您是VIP会员享受8折优惠,商品名称:" + name + "数量:" + amount + "价格:" + price + "应付金额:" + sum); } }
运行结果:
您是普通客户没有折扣,商品名称:CD唱片数量:2价格:50应付金额:100.0
您是会员享受9折优惠,商品名称:CD唱片数量:2价格:50应付金额:90.0
您是VIP会员享受8折优惠,商品名称:CD唱片数量:2价格:50应付金额:80.0