2021年7月29日星期四

迭代器模式(学习笔记)

  1. 意图

  提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象内部表示

  2. 动机

  有时候,会使用不同的算法来遍历集合中的元素,不断地向集合中添加遍历算法会模糊其高效存储数据的主要职责。此外,有些算法可能是根据特定应用订制的,将其加入到泛型集合类中会显得非常奇怪。另一方面,使用多种集合的客户端代码可能并不关心存储数据的方式。不过,由于集合提供不同的元素访问方式,代码将不得不与特定的集合类耦合。迭代器模式的主要思想是将集合的遍历行为抽取为单独的迭代器对象。除实现自身算法外, 迭代器还封装了遍历操作的所有细节, 例如当前位置和末尾剩余元素的数量。 因此, 多个迭代器可以在相互独立的情况下同时访问集合。迭代器通常会提供一个获取集合元素的基本方法。 客户端可不断调用该方法直至它不返回任何内容, 这意味着迭代器已经遍历了所有元素。所有迭代器必须实现相同的接口。 这样一来, 只要有合适的迭代器, 客户端代码就能兼容任何类型的集合或遍历算法。 如果你需要采用特殊方式来遍历集合, 只需创建一个新的迭代器类即可, 无需对集合或客户端进行修改。

  3. 适用性

  • 访问一个聚合对象的内容而无须暴露它的内部表示
  • 支持对聚合对象的多种遍历
  • 为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)

  4. 结构

  

  5. 效果

  1)单一职责原则。通过将体积庞大的遍历算法代码抽取为独立的类,可对客户端代码和集合进行整理

  2) 开闭原则。 可以实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码

  3)可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态

  4)如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正

  6. 代码实现

  iterators/ProfileIterator.java: 定义档案接口

package iterator.iterators;import iterator.profile.Profile;/** * @author GaoMing * @date 2021/7/19 - 19:24 */public interface ProfileIterator { boolean hasNext(); Profile getNext(); void reset();}

  iterators/FacebookIterator.java: 在 Facebook 档案上实现迭代

package iterator.iterators;import iterator.profile.Profile;import iterator.social_networks.Facebook;import java.util.ArrayList;import java.util.List;/** * @author GaoMing * @date 2021/7/19 - 19:23 */public class FacebookIterator implements ProfileIterator{ private Facebook facebook; private String type; private String email; private int currentPosition = 0; private List<String> emails = new ArrayList<>(); private List<Profile> profiles = new ArrayList<>(); public FacebookIterator(Facebook facebook, String type, String email) {  this.facebook = facebook;  this.type = type;  this.email = email; } private void lazyLoad() {  if (emails.size() == 0) {   List<String> profiles = facebook.requestProfileFriendsFromFacebook(this.email, this.type);   for (String profile : profiles) {    this.emails.add(profile);    this.profiles.add(null);   }  } } @Override public boolean hasNext() {  lazyLoad();  return currentPosition < emails.size(); } @Override public Profile getNext() {  if (!hasNext()) {   return null;  }  String friendEmail = emails.get(currentPosition);  Profile friendProfile = profiles.get(currentPosition);  if (friendProfile == null) {   friendProfile = facebook.requestProfileFromFacebook(friendEmail);   profiles.set(currentPosition, friendProfile);  }  currentPosition++;  return friendProfile; } @Override public void reset() {  currentPosition = 0; }}

  iterators/LinkedInIterator.java: 在领英档案上实现迭代

package iterator.iterators;import iterator.profile.Profile;import iterator.social_networks.LinkedIn;import java.util.ArrayList;import java.util.List;/** * @author GaoMing * @date 2021/7/19 - 19:24 */public class LinkedInIterator implements ProfileIterator{ private LinkedIn linkedIn; private String type; private String email; private int currentPosition = 0; private List<String> emails = new ArrayList<>(); private List<Profile> contacts = new ArrayList<>(); public LinkedInIterator(LinkedIn linkedIn, String type, String email) {  this.linkedIn = linkedIn;  this.type = type;  this.email = email; } private void lazyLoad() {  if (emails.size() == 0) {   List<String> profiles = linkedIn.requestRelatedContactsFromLinkedInAPI(this.email, this.type);   for (String profile : profiles) {    this.emails.add(profile);    this.contacts.add(null);   }  } } @Override public boolean hasNext() {  lazyLoad();  return currentPosition < emails.size(); } @Override public Profile getNext() {  if (!hasNext()) {   return null;  }  String friendEmail = emails.get(currentPosition);  Profile friendContact = contacts.get(currentPosition);  if (friendContact == null) {   friendContact = linkedIn.requestContactInfoFromLinkedInAPI(friendEmail);   contacts.set(currentPosition, friendContact);  }  currentPosition++;  return friendContact; } @Override public void reset() {  currentPosition = 0; }}

  social_networks/SocialNetwork.java: 定义通用的社交网络接口

package iterator.social_networks;import iterator.iterators.ProfileIterator;/** * @author GaoMing * @date 2021/7/19 - 19:31 */public interface SocialNetwork { ProfileIterator createFriendsIterator(String profileEmail); ProfileIterator createCoworkersIterator(String profileEmail);}

  social_networks/Facebook.java: Facebook

package iterator.social_networks;import iterator.iterators.FacebookIterator;import iterator.iterators.ProfileIterator;import iterator.profile.Profile;import java.util.ArrayList;import java.util.List;/** * @author GaoMing * @date 2021/7/19 - 19:30 */public class Facebook implements SocialNetwork{ private List<Profile> profiles; public Facebook(List<Profile> cache) {  if (cache != null) {   this.profiles = cache;  } else {   this.profiles = new ArrayList<>();  } } public Profile requestProfileFromFacebook(String profileEmail) {  // Here would be a POST request to one of the Facebook API endpoints.  // Instead, we emulates long network connection, which you would expect  // in the real life...  simulateNetworkLatency();  System.out.println("Facebook: Loading profile '" + profileEmail + "' over the network...");  // ...and return test data.  return findProfile(profileEmail); } public List<String> requestProfileFriendsFromFacebook(String profileEmail, String contactType) {  // Here would be a POST request to one of the Facebook API endpoints.  // Instead, we emulates long network connection, which you would expect  // in the real life...  simulateNetworkLatency();  System.out.println("Facebook: Loading '" + contactType + "' list of '" + profileEmail + "' over the network...");  // ...and return test data.  Profile profile = findProfile(profileEmail);  if (profile != null) {   return profile.getContacts(contactType);  }  return null; } private Profile findProfile(String profileEmail) {  for (Profile profile : profiles) {   if (profile.getEmail().equals(profileEmail)) {    return profile;   }  }  return null; } private void simulateNetworkLatency() {  try {   Thread.sleep(2500);  } catch (InterruptedException ex) {   ex.printStackTrace();  } } @Override public ProfileIterator createFriendsIterator(String profileEmail) {  return new FacebookIterator(this, "friends", profileEmail); } @Override public ProfileIterator createCoworkersIterator(String profileEmail) {  return new FacebookIterator(this, "coworkers", profileEmail); }}

  social_networks/LinkedIn.java: 领英

package iterator.social_networks;import iterator.iterators.LinkedInIterator;import iterator.iterators.ProfileIterator;import iterator.profile.Profile;import java.util.ArrayList;import java.util.List;/** * @author GaoMing * @date 2021/7/19 - 19:32 */public class LinkedIn implements SocialNetwork{ private List<Profile> contacts; public LinkedIn(List<Profile> cache) {  if (cache != null) {   this.contacts = cache;  } else {   this.contacts = new ArrayList<>();  } } public Profile requestContactInfoFromLinkedInAPI(String profileEmail) {  // Here would be a POST request to one of the LinkedIn API endpoints.  // Instead, we emulates long network connection, which you would expect  // in the real life...  simulateNetworkLatency();  System.out.println("LinkedIn: Loading profile '" + profileEmail + "' over the network...");  // ...and return test data.  return findContact(profileEmail); } public List<String> requestRelatedContactsFromLinkedInAPI(String profileEmail, String contactType) {  // Here would be a POST request to one of the LinkedIn API endpoints.  // Instead, we emulates long network connection, which you would expect  // in the real life.  simulateNetworkLatency();  System.out.println("LinkedIn: Loading '" + contactType + "' list of '" + profileEmail + "' over the network...");  // ...and return test data.  Profile profile = findContact(profileEmail);  if (profile != null) {   return profile.getContacts(contactType);  }  return null; } private Profile findContact(String profileEmail) {  for (Profile profile : contacts) {   if (profile.getEmail().equals(profileEmail)) {    return profile;   }  }  return null; } private void simulateNetworkLatency() {  try {   Thread.sleep(2500);  } catch (InterruptedException ex) {   ex.printStackTrace();  } } @Override public ProfileIterator createFriendsIterator(String profileEmail) {  return new LinkedInIterator(this, "friends", profileEmail); } @Override public ProfileIterator createCoworkersIterator(String profileEmail) {  return new LinkedInIterator(this, "coworkers", profileEmail); }}

  profile/Profile.java: 社交档案

package iterator.profile;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @author GaoMing * @date 2021/7/19 - 19:25 */public class Profile { private String name; private String email; private Map<String, List<String>> contacts = new HashMap<>(); public Profile(String email, String name, String... contacts) {  this.email = email;  this.name = name;  // Parse contact list from a set of "friend:email@gmail.com" pairs.  for (String contact : contacts) {   String[] parts = contact.split(":");   String contactType = "friend", contactEmail;   if (parts.length == 1) {    contactEmail = parts[0];   }   else {    contactType = parts[0];    contactEmail = parts[1];   }   if (!this.contacts.containsKey(contactType)) {    this.contacts.put(contactType, new ArrayList<>());   }   this.contacts.get(contactType).add(contactEmail);  } } public String getEmail() {  return email; } public String getName() {  return name; } public List<String> getContacts(String contactType) {  if (!this.contacts.containsKey(contactType)) {   this.contacts.put(contactType, new ArrayList<>());  }  return contacts.get(contactType); }}

  spammer/SocialSpammer.java: 消息发送应用

package iterator.spammer;import iterator.iterators.ProfileIterator;import iterator.profile.Profile;import iterator.social_networks.SocialNetwork;/** * @author GaoMing * @date 2021/7/19 - 19:33 */public class SocialSpammer { public SocialNetwork network; public ProfileIterator iterator; public SocialSpammer(SocialNetwork network) {  this.network = network; } public void sendSpamToFriends(String profileEmail, String message) {  System.out.println("\nIterating over friends...\n");  iterator = network.createFriendsIterator(profileEmail);  while (iterator.hasNext()) {   Profile profile = iterator.getNext();   sendMessage(profile.getEmail(), message);  } } public void sendSpamToCoworkers(String profileEmail, String message) {  System.out.println("\nIterating over coworkers...\n");  iterator = network.createCoworkersIterator(prof......

原文转载:http://www.shaoqun.com/a/892290.html

跨境电商:https://www.ikjzd.com/

moss:https://www.ikjzd.com/w/1653

3suisses:https://www.ikjzd.com/w/412

淘粉吧返利:https://www.ikjzd.com/w/1725


1.意图  提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象内部表示  2.动机  有时候,会使用不同的算法来遍历集合中的元素,不断地向集合中添加遍历算法会模糊其高效存储数据的主要职责。此外,有些算法可能是根据特定应用订制的,将其加入到泛型集合类中会显得非常奇怪。另一方面,使用多种集合的客户端代码可能并不关心存储数据的方式。不过,由于集合提供不同的元素访问方式,代码将不得不与特定
3suisses:https://www.ikjzd.com/w/412
四川乡村旅游连连看 :http://www.30bags.com/a/409522.html
四川香格里拉与云南香格里拉之比较 :http://www.30bags.com/a/408178.html
四川小吃-玻璃烧麦 - :http://www.30bags.com/a/402217.html
四川小吃-灯影牛肉 - :http://www.30bags.com/a/402219.html
趴着把腿张开给男友进 我张开双腿疯狂迎合他:http://lady.shaoqun.com/m/a/247414.html
校花被校长啪到腿软 啊校长你慢点啊好大啊:http://lady.shaoqun.com/m/a/247765.html
宝贝腿张开点我轻点两男一女 男同桌把舌头伸进我下面:http://lady.shaoqun.com/m/a/248327.html
深圳宝安科技馆8月展览汇总(持续更新):http://www.30bags.com/a/517601.html
2021时尚深圳展蝶讯馆展览好看吗:http://www.30bags.com/a/517602.html
2021时尚深圳蝶讯馆观展攻略:http://www.30bags.com/a/517603.html
深圳欢乐谷夏浪音乐节有朱星杰吗:http://www.30bags.com/a/517604.html

没有评论:

发表评论