zoukankan      html  css  js  c++  java
  • 模式-“里氏替换原则”

    里氏替换原则是,同组的有类的两个子类,在使用子类A这个地方(方法/属性)您可以使用子类
    B代替.对于面向接口编程,我只需要确保同样的行为代码;基类的所有子类必须全部
    实现,换过来,子类的方法基类不一定都有;

    如果:有一个基类Base;其子类是Concrete;那么method(Base b)的调用能够转换成
    method(Concrete c);
    策略模式:一般,我们把解决某个问题的方法称为一个"算法",而把解决一类问题的算法封装
    成一个接口,那么实现算法的多种方式作为子类;在某个时候,在调用中我们使用算法A替换
    算法B,这就是策略模式在里氏代换原则中的应用;
    ***************策略模式************************************
    >准备一组算法,并将每个封装起来使的他们能够互换.

    Context   

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class Context {
    
    	public static Strategy strategy;
    	
    	public static void main(String[] args) {
    		strategy=new ConcreteStrategyA();
    		strategy.calculate();
    	}
    	
    }
    
    abstract class Strategy{
    	
    	public abstract void calculate();
    	
    }
    
    class ConcreteStrategyA extends Strategy{
    
    	@Override
    	public void calculate() {
    		System.out.println("ConcreteStrategyA is called !");
    	}
    	
    }
    
    class ConcreteStrategyB extends Strategy{
    	
    	@Override
    	public void calculate() {
    		System.out.println("ConcreteStrategyB is called !");
    	}
    	
    


    IChoiceStrategy

    /**
     * 		选择策略
     * 
     * 	@author Lean  @date:2014-10-17  
     */
    public abstract class IChoiceStrategy {
    
    	/**
    	 * @return	返回列表名字
    	 */
    	public abstract String[] getNames();
    	
    	/**
    	 * @return	返回相应码
    	 */
    	public abstract int getCode(String name);
    	
    }
    

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class SortChoiceStrategy extends IChoiceStrategy {
    	
    	private HashMap<String, Integer> mSortMap;
    	public String name;
    	
    	public SortChoiceStrategy() {
    		initSortMap();
    	}
    
    	private void initSortMap() {
    		mSortMap=new HashMap<String, Integer>();
    		mSortMap.put("最新上架", 0);
    		mSortMap.put("销量最高", 1);
    		mSortMap.put("价格最高", 2);
    		mSortMap.put("价格最低", 3);
    		name="最新上架";
    	}
    
    	@Override
    	public String[] getNames() {
    		Set<String> set=mSortMap.keySet();
    		Object[] tempObj=set.toArray();
    		String[] result=new String[tempObj.length];
    		for (int i = 0; i < tempObj.length; i++) {
    			result[i]=(String) tempObj[i];
    		}
    		return result;
    	}
    
    	@Override
    	public int getCode(String name) {
    		return mSortMap.get(name);
    	}
    
    }
    

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class StatusChoiceStrategy extends IChoiceStrategy {
    	
    	private HashMap<String, Integer> mStatusMap;
    	public String name;
    	
    	public StatusChoiceStrategy() {
    		initStatusMap();
    	}
    	
    	private void initStatusMap() {
    		mStatusMap=new HashMap<String, Integer>();
    		mStatusMap.put("定制中", 1);
    		mStatusMap.put("已完毕", 2);
    		name="定制中";
    	}
    
    	@Override
    	public String[] getNames() {
    		Set<String> set=mStatusMap.keySet();
    		Object[] tempObj=set.toArray();
    		String[] result=new String[tempObj.length];
    		for (int i = 0; i < tempObj.length; i++) {
    			result[i]=(String) tempObj[i];
    		}
    		return result;
    	}
    
    	@Override
    	public int getCode(String name) {
    		return mStatusMap.get(name);
    	}
    
    }
    
    ***********************************************************

    代理模式:代理和被代理对象相同拥有一样的行为,我们把它封装成一个接口,那么,在被
    代理对象被调用的地方都能够使用代理对象替换以隐藏实现细节;
    ***************代理模式************************************
    如果一个场景,A想去买票,但A没时间,于是A托B到电影院帮他买票;
    换成面向对象思维:如果有一个对象A,和一个新的对象C,如今C想使用对象A,而A临时还
    不符合C的要求,这时能够间接的使用B以达到使用A的目的,同一时候,B又能够对使用过程进行

    拦截,如打印日志;(像这样的利用中间层来达到目的的模式还有适配器模式)

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public abstract class IPerson {
    	
    	public abstract void buyTicket();
    	
    }
    

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class RealSeePerson extends IPerson {
    
    	@Override
    	public void buyTicket() {
    		System.out.println("RealSeePerson get the ticket !");
    	}
    
    }
    

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class BuyTicketPerson extends IPerson{
    	
    	public RealSeePerson target;
    	
    	private void preBuyTicket(){
    		//TODO do th. before buy ticket
    		target=new RealSeePerson();
    	}
    	
    	@Override
    	public void buyTicket() {
    		preBuyTicket();
    		if (target!=null) {
    			target.buyTicket();
    		}
    		postBuyTicket();
    	}
    	
    	public void postBuyTicket(){
    		//TODO do th. after buy thicket
    	}
    	
    }
    

    >代理和被代理对象实现共同接口,代理对象被调用时调用被代理对象的托付;

    动态代理实现监听:

    /**
     * 	@author Lean  @date:2014-10-17  
     */
    public class VectorProxy implements InvocationHandler {
    	
    	private Object proxyobj;
    	
    	public VectorProxy(Object obj) {
    		proxyobj=obj;
    	}
    	
    	public static Object factor(Object obj){
    		Class cls=obj.getClass();
    		return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new VectorProxy(obj));
    	}
    	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		System.out.println("method:"+method.getName());
    		if (args!=null) {
    			for (int i = 0; i < args.length; i++) {
    				System.out.println(args[i]+"");
    			}
    		}
    		//反射调用
    		Object obj=method.invoke(proxyobj, args);
    		System.out.println("*********");
    		return obj;
    	}
    	
    	public static void main(String[] args) {
    		List v=null;
    		//返回代理对象,并调用代理对象的add方法
    		v=(List) factor(new Vector(10));
    		v.add("New");
    	}
    	
    
    }
    
    ***********************************************************

    合成模式:上面两中模式都是里氏代换原则在方法方面的应用.合成模式使用树结果描写叙述
    总体和部分的关系,由于单纯元素和复合元素相同实现抽象,那么在抽象使用的地方,
    都能够这2种元素替代;
    ***************合成模式************************************

    合成模式分为透明式和安全式

    透明:指抽象接口声明了枝叶全部的全部接口方法,在叶子类中。对该方法进行空实现;

    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public interface Component {
    	
    	void sampleOperation();
    
    	Composite getComposite();
    	
    	void add(Component component);
    	
    	void remove(Component component);
    	
    	Enumeration<Component> components();
    	
    }
    
    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public class Composite implements Component {
    	
    	private Vector<Component> componentVector=new Vector<Component>();
    	
    	@Override
    	public Composite getComposite() {
    		return this;
    	}
    
    	@Override
    	public void sampleOperation() {
    		Enumeration<Component> enumeration=components();
    		while (enumeration.hasMoreElements()) {
    			Component component = (Component) enumeration.nextElement();
    			component.sampleOperation();
    		}
    	}
    
    	@Override
    	public void add(Component component) {
    		componentVector.addElement(component);
    	}
    
    	@Override
    	public void remove(Component component) {
    		componentVector.removeElement(component);
    	}
    
    	@Override
    	public Enumeration<Component> components() {
    		return componentVector.elements();
    	}
    
    }
    
    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public class Leaf implements Component {
    
    	@Override
    	public Composite getComposite() {
    		return null;
    	}
    
    	@Override
    	public void sampleOperation() {
    		System.out.println(" call leaf here !");
    	}
    
    	@Override
    	public void add(Component component) {
    		
    	}
    
    	@Override
    	public void remove(Component component) {
    		
    	}
    
    	@Override
    	public Enumeration<Component> components() {
    		return null;
    	}
    
    }
    

    安全:指抽象接口仅仅声明叶子全部的方法,树枝类除了继承还包含了自己的管理叶子类方法;典型应用:Android的View,ViewGroup

    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public interface Component {
    
    	Composite getComposite();
    	
    	void sampleOperation();
    	
    }
    
    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public class Composite implements Component {
    	
    	private Vector componentVector=new Vector();
    	
    	@Override
    	public void sampleOperation() {
    		Enumeration enumeration=components();
    		while (enumeration.hasMoreElements()) {
    			((Component) enumeration.nextElement()).sampleOperation();
    		}
    	}
    
    	@Override
    	public Composite getComposite() {
    		return this;
    	}
    	
    	public Enumeration components(){
    		return componentVector.elements();
    	}
    	
    	public void add(Component component){
    		componentVector.addElement(component);
    	}
    	
    	public void remove(Component component){
    		componentVector.removeElement(component);
    	}
    	
    }
    
    /**
     * 	@author Lean  @date:2014-10-20  
     */
    public class Leaf implements Component {
    
    	@Override
    	public Composite getComposite() {
    		return null;
    	}
    
    	@Override
    	public void sampleOperation() {
    		System.out.println("leaf is called !");
    	}
    
    }
    

    由于分支机构基本继承抽象类,在抽象方法只支持类,那里可以换成一个叶子。例如,在安全模式。叶类可以换成棒/多叶;在透明模式下可以互换。这是与里氏代换原则;

    ***********************************************************


  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4619449.html
Copyright © 2011-2022 走看看