<?xml version="1.0"?>
<News hasArchived="true" page="7882" pageCount="10751" pageSize="10" timestamp="Sat, 15 Aug 2026 04:25:20 -0400" url="https://my3.my.umbc.edu/posts.xml?mode=activity&amp;page=7882">
<NewsItem contentIssues="true" id="40419" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40419">
<Title>DealBook: A Globe-Trotting Serial Entrepreneur Finds Roots in China&#8217;s Start-Up Scene</Title>
<Body>
<![CDATA[
    <div class="html-content">Richard Robinson has spent more than a dozen years in Beijing, where he has mainly focused on mobile Internet and gaming.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fa-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+A+Globe-Trotting+Serial+Entrepreneur+Finds+Roots+in+China%E2%80%99s+Start-Up+Scene" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fa-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+A+Globe-Trotting+Serial+Entrepreneur+Finds+Roots+in+China%E2%80%99s+Start-Up+Scene" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fa-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+A+Globe-Trotting+Serial+Entrepreneur+Finds+Roots+in+China%E2%80%99s+Start-Up+Scene" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fa-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+A+Globe-Trotting+Serial+Entrepreneur+Finds+Roots+in+China%E2%80%99s+Start-Up+Scene" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fa-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+A+Globe-Trotting+Serial+Entrepreneur+Finds+Roots+in+China%E2%80%99s+Start-Up+Scene" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/sc/21/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571854/u/0/f/640387/c/34625/s/3625b0dc/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>Richard Robinson has spent more than a dozen years in Beijing, where he has mainly focused on mobile Internet and gaming.      </Summary>
<Website>http://dealbook.nytimes.com/2014/01/20/a-globetrotting-serial-entrepreneur-finds-roots-in-chinas-start-up-scene/?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40419/guest@my.umbc.edu/282bd8a5910e7a070adb813314b79206/api/pixel</TrackingUrl>
<Tag>500-startups</Tag>
<Tag>china</Tag>
<Tag>computer-and-video-games</Tag>
<Tag>computers-and-the-internet</Tag>
<Tag>entrepreneurship</Tag>
<Tag>new</Tag>
<Tag>rotterdam-school-of-management</Tag>
<Tag>start-ups</Tag>
<Tag>technology</Tag>
<Tag>tencent-holdings-ltd</Tag>
<Tag>top-headline-2</Tag>
<Tag>vivendi-games</Tag>
<Tag>walt-disney-company</Tag>
<Tag>walt-disney-company-dis-nyse</Tag>
<Tag>wireless-communications</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 19:44:22 -0500</PostedAt>
<EditAt>Tue, 21 Jan 2014 16:49:09 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="40420" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40420">
<Title>Theft of Data Fuels Worries in South Korea</Title>
<Body>
<![CDATA[
    <div class="html-content">A string of senior executives at three credit card companies offered to resign on Monday after a huge theft of client data may have affected 20 million people.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Fbusiness%2Finternational%2Ftheft-of-data-fuels-worries-in-south-korea.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Theft+of+Data+Fuels+Worries+in+South+Korea" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Fbusiness%2Finternational%2Ftheft-of-data-fuels-worries-in-south-korea.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Theft+of+Data+Fuels+Worries+in+South+Korea" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Fbusiness%2Finternational%2Ftheft-of-data-fuels-worries-in-south-korea.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Theft+of+Data+Fuels+Worries+in+South+Korea" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Fbusiness%2Finternational%2Ftheft-of-data-fuels-worries-in-south-korea.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Theft+of+Data+Fuels+Worries+in+South+Korea" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Fbusiness%2Finternational%2Ftheft-of-data-fuels-worries-in-south-korea.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Theft+of+Data+Fuels+Worries+in+South+Korea" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/sc/2/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571853/u/0/f/640387/c/34625/s/3625b0de/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>A string of senior executives at three credit card companies offered to resign on Monday after a huge theft of client data may have affected 20 million people.      </Summary>
<Website>http://www.nytimes.com/2014/01/21/business/international/theft-of-data-fuels-worries-in-south-korea.html?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40420/guest@my.umbc.edu/0952e2447140b47933d58df73c4a363e/api/pixel</TrackingUrl>
<Tag>computer-security</Tag>
<Tag>credit-cards</Tag>
<Tag>cyberattacks-and-hackers</Tag>
<Tag>google-inc-goog-nasdaq</Tag>
<Tag>new</Tag>
<Tag>south-korea</Tag>
<Tag>technology</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 19:25:55 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40421" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40421">
<Title>A Popular Chinese Social Networking App Blazes Its Own Path</Title>
<Body>
<![CDATA[
    <div class="html-content">Weixin, a fast-growing app from the Chinese Internet company Tencent, is no mere copy of any existing service, and its success may thwart Facebook’s ambitions in China.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Ftechnology%2Fa-chinese-social-network-blazes-its-own-path.html%3Fpartner%3Drss%26emc%3Drss&amp;t=A+Popular+Chinese+Social+Networking+App+Blazes+Its+Own+Path" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Ftechnology%2Fa-chinese-social-network-blazes-its-own-path.html%3Fpartner%3Drss%26emc%3Drss&amp;t=A+Popular+Chinese+Social+Networking+App+Blazes+Its+Own+Path" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Ftechnology%2Fa-chinese-social-network-blazes-its-own-path.html%3Fpartner%3Drss%26emc%3Drss&amp;t=A+Popular+Chinese+Social+Networking+App+Blazes+Its+Own+Path" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Ftechnology%2Fa-chinese-social-network-blazes-its-own-path.html%3Fpartner%3Drss%26emc%3Drss&amp;t=A+Popular+Chinese+Social+Networking+App+Blazes+Its+Own+Path" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F01%2F21%2Ftechnology%2Fa-chinese-social-network-blazes-its-own-path.html%3Fpartner%3Drss%26emc%3Drss&amp;t=A+Popular+Chinese+Social+Networking+App+Blazes+Its+Own+Path" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/sc/46/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187556571852/u/0/f/640387/c/34625/s/3625b0d9/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>Weixin, a fast-growing app from the Chinese Internet company Tencent, is no mere copy of any existing service, and its success may thwart Facebook’s ambitions in China.      </Summary>
<Website>http://www.nytimes.com/2014/01/21/technology/a-chinese-social-network-blazes-its-own-path.html?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40421/guest@my.umbc.edu/d9b936796209ec91a957b005fcb0838b/api/pixel</TrackingUrl>
<Tag>barclays-plc-bcs-nyse</Tag>
<Tag>china</Tag>
<Tag>china-mobile-ltd-chl-nyse</Tag>
<Tag>ebay-inc-ebay-nasdaq</Tag>
<Tag>facebook-inc-fb-nasdaq</Tag>
<Tag>forrester-research-inc-forr-nasdaq</Tag>
<Tag>google-inc-goog-nasdaq</Tag>
<Tag>new</Tag>
<Tag>social-media</Tag>
<Tag>technology</Tag>
<Tag>tencent-holdings-ltd</Tag>
<Tag>twitter-twtr-nyse</Tag>
<Tag>weixin</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 18:52:26 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="40424" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40424">
<Title>Programmatically Trigger an Application Cache Download</Title>
<Body>
<![CDATA[
    <div class="html-content"><p>Rob Gravelle shows how to dynamically kick off an Application Cache download via a user action such as a button click.</p></div>
]]>
</Body>
<Summary>Rob Gravelle shows how to dynamically kick off an Application Cache download via a user action such as a button click.</Summary>
<Website>http://www.htmlgoodies.com/HTML5/javascript/programmatically-trigger-an-application-cache-download.html</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40424/guest@my.umbc.edu/c9651b0f0c38510e12fc356a3f4a2365/api/pixel</TrackingUrl>
<Tag>html</Tag>
<Tag>htmlgoodies</Tag>
<Tag>learning</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 18:49:00 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40417" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40417">
<Title>DealBook: IBM Restarts Talks on Low-End Server Business</Title>
<Body>
<![CDATA[
    <div class="html-content">A sale would be the latest step in IBM’s evolution from a dominant producer of hardware like computers and servers into a company focused on providing services to governments and businesses.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fibm-restarts-talks-on-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+IBM+Restarts+Talks+on+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fibm-restarts-talks-on-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+IBM+Restarts+Talks+on+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fibm-restarts-talks-on-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+IBM+Restarts+Talks+on+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fibm-restarts-talks-on-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+IBM+Restarts+Talks+on+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fdealbook.nytimes.com%2F2014%2F01%2F20%2Fibm-restarts-talks-on-low-end-server-business%2F%3Fpartner%3Drss%26emc%3Drss&amp;t=DealBook%3A+IBM+Restarts+Talks+on+Low-End+Server+Business" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/sc/21/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186529263102/u/0/f/640387/c/34625/s/362504b9/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>A sale would be the latest step in IBM’s evolution from a dominant producer of hardware like computers and servers into a company focused on providing services to governments and businesses.      </Summary>
<Website>http://dealbook.nytimes.com/2014/01/20/ibm-restarts-talks-on-low-end-server-business/?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40417/guest@my.umbc.edu/33b9551eb49b9f06f1f12855e1df28b9/api/pixel</TrackingUrl>
<Tag>mergers-and-acquisitions</Tag>
<Tag>new</Tag>
<Tag>technology</Tag>
<Tag>top-headline-2</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 18:17:31 -0500</PostedAt>
<EditAt>Tue, 21 Jan 2014 16:54:49 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="40418" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40418">
<Title>Changing Between Spaces and Tabs in Sublime Text</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>Sublime Text is pretty dang good at making it easy to switch between using tabs and spaces to indent your code. More importantly, it makes it easy to adjust the indentation of code that doesn't match your preference. I thought I'd put this together for reference, as there is a particular sequence of steps for some of the transitions that needs to be followed.</p>
    <p></p>
    <p>The first step is making sure your User Preferences are how you like them.</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/user-prefs.png" alt="" style="max-width: 100%; height: auto;">
    <p>I prefer spaces, so my settings are like this:</p>
    <pre><code>{&#x000A;      // other stuff&#x000A;    &#x000A;      "tab_size": 2,&#x000A;      "translate_tabs_to_spaces": true,&#x000A;    &#x000A;       // more other stuff&#x000A;    }</code></pre>
    <p>Adjust to your liking there.</p>
    <p>You can override these settings on any given file, from the bottom right.</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/current-settings.png" alt="" style="max-width: 100%; height: auto;">
    The bottom right corner is where you can see the current settings for the open document.
    
    <p>This is also headquarters for fixing up a document that isn't how you like it. </p>
    <h3>Changing from Tabs to Spaces (Same Level of Indentation)</h3>
    <p>Here's a document that is in tabs right now. I can tell because I've selected the text and there are dashes in the white space not dots. Dashes are tabs, dots are spaces. Also, in the bottom right, I can see it says "Tabs Size: 2".</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/doc-in-tabs.png" alt="" style="max-width: 100%; height: auto;">
    <p>You can see that those Tabs are 2 spaces wide. Assuming I want to switch to spaces and I'm happy with 2 spaces per tab, I just select "Convert Indentation To Spaces" from that menu.</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/tabs-to-spaces-same.gif" alt="" style="max-width: 100%; height: auto;">
    <p>And I'm good to go for that case.</p>
    <h3>Changing from Tabs to Spaces (Different Level of Indentation)</h3>
    <p>Let's say a straight conversion from tabs to spaces isn't going to do it for me. Say the tab level is set to 6 spaces per tab, and I want to convert to spaces, but only 2 spaces per indentation. The trick here is to adjust the spacing while in tabs first, then convert.</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/tabs-to-spaces-dif.gif" alt="" style="max-width: 100%; height: auto;">
    <h3>Changing From Spaces to Spaces (Different Level of Indentation)</h3>
    <p>What if you have a file that is in spaces how you like it, but it's using 4 spaces instead of 2? Sublime Text can still help here. You use the ability of tabs to be of variable length. So first convert to tabs, adjust the width, then switch back to spaces.</p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/spaces-to-spaces-dif.gif" alt="" style="max-width: 100%; height: auto;">
    <h3>Changing From Spaces to Tabs</h3>
    <p>I think we're getting the hang of this now. You can do any of this in the reverse direction if you prefer tabs. </p>
    <img src="http://cdn.css-tricks.com/wp-content/uploads/2014/01/spaces-to-tabs-dif.gif" alt="" style="max-width: 100%; height: auto;">
    <hr>
    <p>I think you can extrapolate other switching scenarios from there. </p>
    <p>I don't think there is any scenario that you can't adjust to your liking this way. If you're caught manually adjusting indentation (that is consistent within itself), stop, you can figure out a way to fix it with settings.</p>
    <p>If you want to discuss tabs vs. spaces below, go for it, but I can tell you I really don't care. I mostly care that any particular project is consistent about it and enforces it. </p>
    <h3>.editorconfig</h3>
    <p>Also worth mentioning: There is a thing called <a href="http://editorconfig.org/" rel="nofollow external" class="bo">EditorConfig</a>. You put a file in the root of your project called <code>.editorconfig</code>. If someone opens that project in an editor that supports it, those settings will be honored. <a href="https://github.com/sindresorhus/editorconfig-sublime#readme" rel="nofollow external" class="bo">There is one</a> for SublimeText. </p>
    <p>The file might look something like:</p>
    <pre><code># editorconfig.org&#x000A;    root = true&#x000A;    &#x000A;    [*]&#x000A;    indent_style = space&#x000A;    indent_size = 2&#x000A;    end_of_line = lf&#x000A;    charset = utf-8&#x000A;    trim_trailing_whitespace = true&#x000A;    insert_final_newline = true&#x000A;    &#x000A;    [*.md]&#x000A;    trim_trailing_whitespace = false</code></pre>
    <hr>
    
    <p><small><a href="http://css-tricks.com/changing-spaces-tabs-sublime-text/" rel="nofollow external" class="bo">Changing Between Spaces and Tabs in Sublime Text</a> is a post from <a href="http://css-tricks.com" rel="nofollow external" class="bo">CSS-Tricks</a></small></p>
    </div>
]]>
</Body>
<Summary>Sublime Text is pretty dang good at making it easy to switch between using tabs and spaces to indent your code. More importantly, it makes it easy to adjust the indentation of code that doesn't...</Summary>
<Website>http://css-tricks.com/changing-spaces-tabs-sublime-text/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40418/guest@my.umbc.edu/966e5c1fee152019c86c7e5f5ff31574/api/pixel</TrackingUrl>
<Tag>article</Tag>
<Tag>css</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>tricks</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 18:04:48 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40416" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40416">
<Title>UMBC Hosts Maryland FIRST Lego League Championship</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><span>For the Ninth year, UMBC hosted the Maryland State FIRST LEGO League Championship on March 1<sup>st</sup>, 2014 in the RAC. This year, nearly 350 teams competed in 17 qualifiers around the Maryland area to earn one of the 72 championship slots. Teams </span><span>perf</span><span>orming well in all three judged areas (Project, Robot Design and Core Values) and scored in the top 40% of the Robot rounds at their qualifier, were invited to compete. Maryland FLL is currently run out of the College of Engineering and IT, Mechanical Engineering Department. Several Departments and scholar programs (Meyerhoff, CWIT, Sherman) continue to support the program through volunteering at many of the qualifiers and the state championship.</span></p>
    <p><span>A video of the state championship can be found <a href="http://youtu.be/EGauCLrxsZE" rel="nofollow external" class="bo">here</a>.</span></p>
    <p><span> </span></p>
    <p><span>FIRST® LEGO® League (FLL®) introduces young people, ages 9 to 16* (grades 4-8), to the fun and excitement of science and technology while building self-confidence, knowledge, and valuable career and life skills. FLL challenges kids to think  like scientists and engineers. Alongside adult Mentors, FLL teams research and design their own solutions to a current scientific question or problem using  engineering concepts, presentation techniques, and build autonomous LEGO robots.  In this year’s challenge, NATURE’S FURY’S, students explored the awe-inspiring storms, quakes, waves, and more that we call natural disasters. Teams discovered what can be done  when intense natural events meet the  places people live, work, and play.</span></p>
    <p></p>
    <p><span><br></span></p>
    <p><span>For more information about Maryland FLL, please visit <a href="http://www.mdfirst.org/" rel="nofollow external" class="bo">www.mdfirst.org</a>.</span></p>
    <p><br></p>
    <p><img src="https://my3.my.umbc.edu/system/shared/attachments/news/000/040/416/61b07251e835d37322b7460d2b88c05b/DSC_6448.JPG" style="max-width: 100%; height: auto;"></p>
    <p><img src="https://my3.my.umbc.edu/system/shared/attachments/news/000/040/416/b750f74544cb00c138079607276995e9/DSC_6289.JPG" style="max-width: 100%; height: auto;"></p>
    <p><img src="https://my3.my.umbc.edu/system/shared/attachments/news/000/040/416/1b0251ccb8bd5f9ccf444e4bda7713e3/DSC_5891.JPG" style="max-width: 100%; height: auto;"></p>
    </div>
]]>
</Body>
<Summary>For the Ninth year, UMBC hosted the Maryland State FIRST LEGO League Championship on March 1st, 2014 in the RAC. This year, nearly 350 teams competed in 17 qualifiers around the Maryland area to...</Summary>
<AttachmentKind>Photo</AttachmentKind>
<AttachmentUrl>https://assets2-my.umbc.edu/system/shared/attachments/10cb85c875a8591b4320c582450d95de/6a802270/news/000/040/416/61b07251e835d37322b7460d2b88c05b/DSC_6448.JPG?1390257466</AttachmentUrl>
<Attachments>
<Attachment kind="Photo" url="https://my3.my.umbc.edu/posts/40416/attachments/12239"></Attachment>
<Attachment kind="Photo" url="https://my3.my.umbc.edu/posts/40416/attachments/12240"></Attachment>
<Attachment kind="Photo" url="https://my3.my.umbc.edu/posts/40416/attachments/12241"></Attachment>
</Attachments>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40416/guest@my.umbc.edu/f75bf386abf1fe81686b6185faa0b626/api/pixel</TrackingUrl>
<Group token="me">Mechanical Engineering</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/me</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/xsmall.png?1359683367</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/original.jpg?1359683367</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/xxlarge.png?1359683367</AvatarUrl>
<AvatarUrl size="xlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/xlarge.png?1359683367</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/large.png?1359683367</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/medium.png?1359683367</AvatarUrl>
<AvatarUrl size="small">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/small.png?1359683367</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/xsmall.png?1359683367</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/096/f53891bd1b141a18c1dbc498e1eda286/xxsmall.png?1359683367</AvatarUrl>
<Sponsor>Mechanical Engineering</Sponsor>
<ThumbnailUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/xxlarge.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/xlarge.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="large">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/large.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="medium">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/medium.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="small">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/small.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/xsmall.jpg?1390257283</ThumbnailUrl>
<ThumbnailUrl size="xxsmall">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/040/416/7ea03f4ac6f9e60de3b59ebf784b22d6/xxsmall.jpg?1390257283</ThumbnailUrl>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 17:40:52 -0500</PostedAt>
<EditAt>Thu, 06 Mar 2014 20:26:39 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="41061" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41061">
<Title>SOLID: Part 2 - The Open/Closed Principle</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><a href="http://net.tutsplus.com/tutorials/php/solid-part-1-the-single-responsibility-principle/" rel="nofollow external" class="bo">Single Responsibility (SRP)</a>, Open/Closed (OCP), Liskov's Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write code.</p>
    <p></p>
    <hr>
    <h2>Definition</h2>
    <blockquote>
    <p>Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.</p>
    </blockquote>
    <p>The Open/Closed Principle, OCP in short, is credited to <a href="http://en.wikipedia.org/wiki/Bertrand_Meyer" rel="nofollow external" class="bo">Bertrand Mayer</a>, a French programmer, who first published it in his book n <a href="http://www.amazon.com/Object-Oriented-Software-Construction-CD-ROM-Edition/dp/0136291554" rel="nofollow external" class="bo">Object-Oriented Software Construction</a> in 1988.</p>
    <p>The principle rose in popularity in the early 2000s when it became one of the SOLID principles defined by <a href="http://www.8thlight.com/our-team/robert-martin" rel="nofollow external" class="bo">Robert C. Martin</a> in his book <a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1378755964&amp;sr=1-1&amp;keywords=robert+c+martin" rel="nofollow external" class="bo">Agile Software Development, Principles, Patterns, and Practices</a> and later republished in the C# version of the book <a href="http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258" rel="nofollow external" class="bo">Agile Principles, Patterns, and Practices in C#</a>.</p>
    <p>What we are basically talking about here is to design our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code. This sounds a little bit strange, especially if we are working in languages like Java, C, C++ or C# where it applies not only to the source code itself but to the binary also. We want to create new features in ways that will not require us to redeploy existing binaries, executables or DLLs.</p>
    <hr>
    <h2>OCP in the SOLID Context</h2>
    <p>As we progress with these tutorials, we can put each new principle in the context of the already discussed ones. We already discussed the <a href="http://net.tutsplus.com/tutorials/php/solid-part-1-the-single-responsibility-principle/" rel="nofollow external" class="bo">Single Responsibility (SRP)</a> that stated that a module should have only one reason to change. If we think about OCP and SRP, we can observe that they are complementary. Code specifically designed with SRP in mind will be close to OCP principles or easy to make it respect those principles. When we have code that has a single reason to change, introducing a new feature will create a secondary reason for that change. So both SRP and OCP would be violated. In the same way, if we have code that should only change when its main function changes and should remain unchanged when a new feature is added to it, thus respecting OCP, will mostly respect SRP also.</p>
    <p>This does not mean that SRP always leads to OCP or vice versa, but in most cases if one of them is respected, achieving the second one is quite simple.</p>
    <hr>
    <h2>The Obvious Example of OCP Violation</h2>
    <p>From a purely technical point of view, the Open/Closed Principle is very simple. A simple relationship between two classes, like the one below violates the OCP.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/violate1.png" alt="violate1" width="600" height="109" style="max-width: 100%; height: auto;"><br>
    
    <p>The <code>User</code> class uses the <code>Logic</code> class directly. If we need to implement a second <code>Logic</code> class in a way that will allow us to use both the current one and the new one, the existing <code>Logic</code> class will need to be changed. <code>User</code> is directly tied to the implementation of <code>Logic</code>, there is no way for us to provide a new <code>Logic</code> without affecting the current one. And when we are talking about statically typed languages, it is very possible that the <code>User</code> class will also require changes. If we are talking about compiled languages, most certainly both the <code>User</code> executable and the <code>Logic</code> executable or dynamic library will require recompilation and redeployment to our clients, a process we want to avoid whenever possible.</p>
    <hr>
    <h2>Show Me the Code</h2>
    <p>Based only on the schema above, one can deduce that any class directly using another class would actually violate the Open/Closed Principle. And that is right, strictly speaking. I found it quite interesting to find the limits, the moment when you draw the line and decide that it is more difficult to respect OCP than modify existing code, or the architectural cost does not justify the cost of changing existing code.</p>
    <p>Let's say we want to write a class that can provide progress as a percent for a file that is downloaded through our application. We will have two main classes, a <code>Progress</code> and a <code>File</code>, and I imagine we will want to use them like in the test below.</p>
    <pre>function testItCanGetTheProgressOfAFileAsAPercent() {&#x000A;    	$file = new File();&#x000A;    	$file-&gt;length = 200;&#x000A;    	$file-&gt;sent = 100;&#x000A;    &#x000A;    	$progress = new Progress($file);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>In this test we are a user of <code>Progress</code>. We want to obtain a value as a percent, regardless of the actual file size. We use <code>File</code> as the source of information for our <code>Progress</code>. A file has a length in bytes and a field called <code>sent</code> representing the amount of data sent to the one doing the download. We do not care about how these values are updated in the application. We can assume there is some magical logic doing it for us, so in a test we can set them explicitly.</p>
    <pre>class File {&#x000A;    	public $length;&#x000A;    	public $sent;&#x000A;    }</pre>
    <p>The <code>File</code> class is just a simple data object containing the two fields. Of course in real life, it would probably contain other information and behavior also, like file name, path, relative path, current directory, type, permissions and so on.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $file;&#x000A;    &#x000A;    	function __construct(File $file) {&#x000A;    		$this-&gt;file = $file;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;file-&gt;sent * 100 / $this-&gt;file-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p><code>Progress</code> is simply a class taking a <code>File</code> in its constructor. For clarity, we specified the type of the variable in the constructor's parameters. There is a single useful method on <code>Progress</code>, <code>getAsPercent()</code>, which will take the values sent and length from <code>File</code> and transform them into a percent. Simple, and it works.</p>
    <pre>Testing started at 5:39 PM ...&#x000A;    PHPUnit 3.7.28 by Sebastian Bergmann.&#x000A;    .&#x000A;    Time: 15 ms, Memory: 2.50Mb&#x000A;    OK (1 test, 1 assertion)</pre>
    <p>This code seems to be right, however it violates the Open/Closed Principle. But why? And How?</p>
    <hr>
    <h2>Changing Requirements</h2>
    <p>Every application that is expected to evolve in time will need new features. One new feature for our application could be to allow streaming of music, instead of just downloading files. <code>File</code>'s length is represented in bytes, the music's duration in seconds. We want to offer a nice progress bar to our listeners, but can we reuse the one we already have?</p>
    <p>No, we can not. Our progress is bound to <code>File</code>. It understands only files, even though it could be applied to music content also. But in order to do that we have to modify it, we have to make <code>Progress</code> know about <code>Music</code> and <code>File</code>. If our design would respect OCP, we would not need to touch <code>File</code> or <code>Progress</code>. We could just simply reuse the existing <code>Progress</code> and apply it to <code>Music</code>.</p>
    <hr>
    <h2>Solution 1: Take Advantage of the Dynamic Nature of PHP</h2>
    <p>Dynamically typed languages have the advantages of guessing the types of objects at runtime. This allows us to remove the typehint from <code>Progress</code>' constructor and the code will still work.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $file;&#x000A;    &#x000A;    	function __construct($file) {&#x000A;    		$this-&gt;file = $file;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;file-&gt;sent * 100 / $this-&gt;file-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>Now we can throw anything at <code>Progress</code>. And by anything, I mean literally anything:</p>
    <pre>class Music {&#x000A;    &#x000A;    	public $length;&#x000A;    	public $sent;&#x000A;    &#x000A;    	public $artist;&#x000A;    	public $album;&#x000A;    	public $releaseDate;&#x000A;    &#x000A;    	function getAlbumCoverFile() {&#x000A;    		return 'Images/Covers/' . $this-&gt;artist . '/' . $this-&gt;album . '.png';&#x000A;    	}&#x000A;    }</pre>
    <p>And a <code>Music</code> class like the one above will work just fine. We can test it easily with a very similar test to <code>File</code>.</p>
    <pre>function testItCanGetTheProgressOfAMusicStreamAsAPercent() {&#x000A;    	$music = new Music();&#x000A;    	$music-&gt;length = 200;&#x000A;    	$music-&gt;sent = 100;&#x000A;    &#x000A;    	$progress = new Progress($music);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>So basically, any measurable content can be used with the <code>Progress</code> class. Maybe we should express this in code by changing the variable's name also:</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $measurableContent;&#x000A;    &#x000A;    	function __construct($measurableContent) {&#x000A;    		$this-&gt;measurableContent = $measurableContent;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;measurableContent-&gt;sent * 100 / $this-&gt;measurableContent-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>Good, but we have a huge problem with this approach. When we had <code>File</code> specified as a typehint, we were positive about what our class can handle. It was explicit and if something else came in, a nice error told us so.</p>
    <pre>Argument 1 passed to Progress::__construct()&#x000A;    must be an instance of File,&#x000A;    instance of Music given.</pre>
    <p>But without the typehint, we must rely on the fact that whatever comes in will have two public variables of some exact names like "<code>length</code>" and "<code>sent</code>". Otherwise we will have a refused bequest.</p>
    <blockquote><p>Refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class. ~Source Wikipedia.</p></blockquote>
    <p>This is one of the <em>code smells</em> presented in much more detail in the <a href="https://tutsplus.com/course/detecting-code-smells/" rel="nofollow external" class="bo">Detecting Code Smells</a> premium course. In short, we do not want to end up trying to call methods or access fields on objects that do not conform to our contract. When we had a typehint, the contract was specified by it. The fields and methods of the <code>File</code> class. Now that we have nothing, we can send in anything, even a string and it would result in an ugly error.</p>
    <pre>function testItFailsWithAParameterThatDoesNotRespectTheImplicitContract() {&#x000A;    	$progress = new Progress('some string');&#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>A test like this, where we send in a simple string, will produce a refused bequest:</p>
    <pre>Trying to get property of non-object.</pre>
    <p>While the end result is the same in both cases, meaning the code breaks, the first one produced a nice message. This one, however, is very obscure. There is no way of knowing what the variable is - a string in our case - and what properties were looked for and not found. It is difficult to debug and to solve the problem. A programmer needs to open the <code>Progress</code> class and read it and understand it. The contract, in this case, when we do not explicitly specify the typehint, is defined by the behavior of <code>Progress</code>. It is an implicit contract, known only to <code>Progress</code>. In our example, it is defined by the access to the two fields, <code>sent</code> and <code>length</code>, in the <code>getAsPercent()</code> method. In real life the implicit contract can be very complex and hard to discover by just looking for a few seconds at the class.</p>
    <p>This solution is recommended only if none of the other suggestions below can easily be implemented or if they would inflict serious architectural changes that do not justify the effort.</p>
    <hr>
    <h2>Solution 2: Use the Strategy Design Pattern</h2>
    <p>This is the most common and probably the most appropriate solution to respect OCP. It is simple and effective.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/strategy.png" alt="strategy" width="600" height="294" style="max-width: 100%; height: auto;"><br>
    
    <p>The Strategy Pattern simply introduces the use of an interface. An interface is a special type of entity in Object Oriented Programming (OOP) which defines a contract between a client and a server class. Both classes will adhere to the contract to ensure the expected behavior. There may be several, unrelated, server classes that respect the same contract thus being capable of serving the same client class.</p>
    <pre>interface Measurable {&#x000A;    	function getLength();&#x000A;    	function getSent();&#x000A;    }</pre>
    <p>In an interface we can define only behavior. That is why instead of directly using public variables we will have to think about using getters and setters. Adapting the other classes will not be difficult at this point. Our IDE can do most of the job.</p>
    <pre>function testItCanGetTheProgressOfAFileAsAPercent() {&#x000A;    	$file = new File();&#x000A;    	$file-&gt;setLength(200);&#x000A;    	$file-&gt;setSent(100);&#x000A;    &#x000A;    	$progress = new Progress($file);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>As usual, we start with our tests. We will need to use setters to set the values. If considered mandatory, these setters may also be defined in the <code>Measurable</code> interface. However, be careful what you put there. The interface is to define the contract between the client class <code>Progress</code> and the different server classes like <code>File</code> and <code>Music</code>. Does <code>Progress</code> need to set the values? Probably not. So the setters are highly unlikely to be needed to be defined in the interface. Also, if you would define the setters there, you would force all of the server classes to implement setters. For some of them, it may be logical to have setters, but others may behave totally differently. What if we want to use our <code>Progress</code> class to show the temperature of our oven? The <code>OvenTemperature</code> class may be initialized with the values in the constructor, or obtain the information from a third class. Who knows? To have setters on that class would be odd.</p>
    <pre>class File implements Measurable {&#x000A;    &#x000A;    	private $length;&#x000A;    	private $sent;&#x000A;    &#x000A;    	public $filename;&#x000A;    	public $owner;&#x000A;    &#x000A;    	function setLength($length) {&#x000A;    		$this-&gt;length = $length;&#x000A;    	}&#x000A;    &#x000A;    	function getLength() {&#x000A;    		return $this-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    	function setSent($sent) {&#x000A;    		$this-&gt;sent = $sent;&#x000A;    	}&#x000A;    &#x000A;    	function getSent() {&#x000A;    		return $this-&gt;sent;&#x000A;    	}&#x000A;    &#x000A;    	function getRelativePath() {&#x000A;    		return dirname($this-&gt;filename);&#x000A;    	}&#x000A;    &#x000A;    	function getFullPath() {&#x000A;    		return realpath($this-&gt;getRelativePath());&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>The <code>File</code> class is modified slightly to accommodate the requirements above. It now implements the <code>Measurable</code> interface and has setters and getters for the fields we are interested in. <code>Music</code> is very similar, you can check its content in the attached source code. We are almost done.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $measurableContent;&#x000A;    &#x000A;    	function __construct(Measurable $measurableContent) {&#x000A;    		$this-&gt;measurableContent = $measurableContent;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;measurableContent-&gt;getSent() * 100 / $this-&gt;measurableContent-&gt;getLength();&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p><code>Progress</code> also needed a small update. We can now specify a type, using typehinting, in the constructor. The expected type is <code>Measurable</code>. Now we have an explicit contract. <code>Progress</code> can be sure the accessed methods will be always present because they are defined in the <code>Measurable</code> interface. <code>File</code> and <code>Music</code> can also be sure they can provide all that is needed for <code>Progress</code> by simply implementing all the methods on the interface, a requirement when a class implements an interface.</p>
    <p>This design pattern is explained in greater detail in the <a href="https://tutsplus.com/course/agile-design-patterns/" rel="nofollow external" class="bo">Agile Design Patterns</a> course.</p>
    <h3>A Note on Interface Naming</h3>
    <p>People tend to name interfaces with a capital <code>I</code> in front of them, or with the word "<code>Interface</code>" attached at the end, like <code>IFile</code> or <code>FileInterface</code>. This is an old-style notation imposed by some outdated standards. We are so much past the Hungarian notations or the need to specify the type of a variable or object in its name in order to easier identify it. IDEs identify anything in a split second for us. This allows us to concentrate on what we actually want to abstract.</p>
    <p>Interfaces belong to their clients. Yes. When you want to name an interface you must think of the client and forget about the implementation. When we named our interface Measurable we did so thinking about Progress. If I would be a progress, what would I need to be able to provide the percent? The answer is simple, something we can measure. Thus the name Measurable. </p>
    <p>Another reason is that the implementation can be from various domains. In our case, there are files and music. But we may very well reuse our <code>Progress</code> in a racing simulator. In that case, the measured classes would be Speed, Fuel, etc. Nice, isn't it?</p>
    <hr>
    <h2>Solution 3: Use the Template Method Design Pattern</h2>
    <p>The Template Method design pattern is very similar to the strategy, but instead of an interface it uses an abstract class. It is recommended to use a Template Method pattern when we have a client very specific to our application, with reduced reusability and when the server classes have common behavior.</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/template_method.png" alt="template_method" width="600" height="294" style="max-width: 100%; height: auto;"><br>
    
    <p>This design pattern is explained in greater detail in the <a href="https://tutsplus.com/course/agile-design-patterns/" rel="nofollow external" class="bo">Agile Design Patterns</a> course.</p>
    <hr>
    <h2>A Higher Level View</h2>
    <p>So, how is all of this affecting our high level architecture?</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesign.png" alt="HighLevelDesign" width="600" height="388" style="max-width: 100%; height: auto;"><br>
    
    <p>If the image above represents the current architecture of our application, adding a new module with five new classes (the blue ones) should affect our design in a moderate way (red class).</p>
    
    <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesignWithNewClasses.png" alt="HighLevelDesignWithNewClasses" width="600" height="410" style="max-width: 100%; height: auto;"><br>
    
    <p>In most systems you can't expect absolutely no effect on the existing code when new classes are introduced. However, respecting the Open/Closed Principle will considerably reduce the classes and modules that require constant change. </p>
    <p>As with any other principle, try not to think about everything from before. If you do so, you will end up with an interface for each of your classes. Such a design will be hard to maintain and understand. Usually the safest way to go is to think about the possibilities and if you can determine whether there will be other types of server classes. Many times you can easily imagine a new feature or you can find one on the project's backlog that will produce another server class. In those cases, add the interface from the beginning. If you can not determine, or if you are unsure - most of the time - simply omit it. Let the next programmer, or maybe even yourself, to add the interface when you need a second implementation.</p>
    <hr>
    <h2>Final Thoughts</h2>
    <p>If you follow your discipline and add interfaces as soon as a second server is needed, modifications will be few and easy. Remember, if code required changes once, there is a high possibility it will require change again. When that possibility turns into reality, OCP will save you a lot of time and effort.</p>
    <p>Thank you for reading.</p>
    </div>
]]>
</Body>
<Summary>Single Responsibility (SRP), Open/Closed (OCP), Liskov's Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write...</Summary>
<Website>http://code.tutsplus.com/tutorials/solid-part-2-the-openclosed-principle--net-36600</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41061/guest@my.umbc.edu/f9300d4c40535be5b4b15d4a8e211ca1/api/pixel</TrackingUrl>
<Tag>css</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>wed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 15:09:07 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="40415" important="false" status="posted" url="https://my3.my.umbc.edu/posts/40415">
<Title>SOLID: Part 2 &#8211; The Open/Closed Principle</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=36600&amp;c=1857671581" rel="nofollow external" class="bo"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=36600&amp;c=1857671581" alt="" style="max-width: 100%; height: auto;"></a><p><a href="http://net.tutsplus.com/tutorials/php/solid-part-1-the-single-responsibility-principle/" rel="nofollow external" class="bo">Single Responsibility (SRP)</a>, Open/Closed (OCP), Liskov’s Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write code.</p>
    <p></p>
    <hr>
    <h2>Definition</h2>
    <blockquote><p>Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.</p></blockquote>
    <p>The Open/Closed Principle, OCP in short, is credited to <a href="http://en.wikipedia.org/wiki/Bertrand_Meyer" rel="nofollow external" class="bo">Bertrand Mayer</a>, a French programmer, who first published it in his book n <a href="http://www.amazon.com/Object-Oriented-Software-Construction-CD-ROM-Edition/dp/0136291554" rel="nofollow external" class="bo">Object-Oriented Software Construction</a> in 1988.</p>
    <p>The principle rose in popularity in the early 2000s when it became one of the SOLID principles defined by <a href="http://www.8thlight.com/our-team/robert-martin" rel="nofollow external" class="bo">Robert C. Martin</a> in his book <a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1378755964&amp;sr=1-1&amp;keywords=robert+c+martin" rel="nofollow external" class="bo">Agile Software Development, Principles, Patterns, and Practices</a> and later republished in the C# version of the book <a href="http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258" rel="nofollow external" class="bo">Agile Principles, Patterns, and Practices in C#</a>.</p>
    <p>What we are basically talking about here is to design our modules, classes and functions in a way that when a new functionality is needed, we should not modify our existing code but rather write new code that will be used by existing code. This sounds a little bit strange, especially if we are working in languages like Java, C, C++ or C# where it applies not only to the source code itself but to the binary also. We want to create new features in ways that will not require us to redeploy existing binaries, executables or DLLs.</p>
    <hr>
    <h2>OCP in the SOLID Context</h2>
    <p>As we progress with these tutorials, we can put each new principle in the context of the already discussed ones. We already discussed the <a href="http://net.tutsplus.com/tutorials/php/solid-part-1-the-single-responsibility-principle/" rel="nofollow external" class="bo">Single Responsibility (SRP)</a> that stated that a module should have only one reason to change. If we think about OCP and SRP, we can observe that they are complementary. Code specifically designed with SRP in mind will be close to OCP principles or easy to make it respect those principles. When we have code that has a single reason to change, introducing a new feature will create a secondary reason for that change. So both SRP and OCP would be violated. In the same way, if we have code that should only change when its main function changes and should remain unchanged when a new feature is added to it, thus respecting OCP, will mostly respect SRP also.</p>
    <p>This does not mean that SRP always leads to OCP or vice versa, but in most cases if one of them is respected, achieving the second one is quite simple.</p>
    <hr>
    <h2>The Obvious Example of OCP Violation</h2>
    <p>From a purely technical point of view, the Open/Closed Principle is very simple. A simple relationship between two classes, like the one below violates the OCP.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/violate1.png" alt="violate1" width="600" height="109" style="max-width: 100%; height: auto;"><br> <p>The <code>User</code> class uses the <code>Logic</code> class directly. If we need to implement a second <code>Logic</code> class in a way that will allow us to use both the current one and the new one, the existing <code>Logic</code> class will need to be changed. <code>User</code> is directly tied to the implementation of <code>Logic</code>, there is no way for us to provide a new <code>Logic</code> without affecting the current one. And when we are talking about statically typed languages, it is very possible that the <code>User</code> class will also require changes. If we are talking about compiled languages, most certainly both the <code>User</code> executable and the <code>Logic</code> executable or dynamic library will require recompilation and redeployment to our clients, a process we want to avoid whenever possible.</p>
    <hr>
    <h2>Show Me the Code</h2>
    <p>Based only on the schema above, one can deduce that any class directly using another class would actually violate the Open/Closed Principle. And that is right, strictly speaking. I found it quite interesting to find the limits, the moment when you draw the line and decide that it is more difficult to respect OCP than modify existing code, or the architectural cost does not justify the cost of changing existing code.</p>
    <p>Let’s say we want to write a class that can provide progress as a percent for a file that is downloaded through our application. We will have two main classes, a <code>Progress</code> and a <code>File</code>, and I imagine we will want to use them like in the test below.</p>
    <pre>function testItCanGetTheProgressOfAFileAsAPercent() {&#x000A;    	$file = new File();&#x000A;    	$file-&gt;length = 200;&#x000A;    	$file-&gt;sent = 100;&#x000A;    &#x000A;    	$progress = new Progress($file);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>In this test we are a user of <code>Progress</code>. We want to obtain a value as a percent, regardless of the actual file size. We use <code>File</code> as the source of information for our <code>Progress</code>. A file has a length in bytes and a field called <code>sent</code> representing the amount of data sent to the one doing the download. We do not care about how these values are updated in the application. We can assume there is some magical logic doing it for us, so in a test we can set them explicitly.</p>
    <pre>class File {&#x000A;    	public $length;&#x000A;    	public $sent;&#x000A;    }</pre>
    <p>The <code>File</code> class is just a simple data object containing the two fields. Of course in real life, it would probably contain other information and behavior also, like file name, path, relative path, current directory, type, permissions and so on.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $file;&#x000A;    &#x000A;    	function __construct(File $file) {&#x000A;    		$this-&gt;file = $file;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;file-&gt;sent * 100 / $this-&gt;file-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p><code>Progress</code> is simply a class taking a <code>File</code> in its constructor. For clarity, we specified the type of the variable in the constructor’s parameters. There is a single useful method on <code>Progress</code>, <code>getAsPercent()</code>, which will take the values sent and length from <code>File</code> and transform them into a percent. Simple, and it works.</p>
    <pre>Testing started at 5:39 PM ...&#x000A;    PHPUnit 3.7.28 by Sebastian Bergmann.&#x000A;    .&#x000A;    Time: 15 ms, Memory: 2.50Mb&#x000A;    OK (1 test, 1 assertion)</pre>
    <p>This code seems to be right, however it violates the Open/Closed Principle. But why? And How?</p>
    <hr>
    <h2>Changing Requirements</h2>
    <p>Every application that is expected to evolve in time will need new features. One new feature for our application could be to allow streaming of music, instead of just downloading files. <code>File</code>‘s length is represented in bytes, the music’s duration in seconds. We want to offer a nice progress bar to our listeners, but can we reuse the one we already have?</p>
    <p>No, we can not. Our progress is bound to <code>File</code>. It understands only files, even though it could be applied to music content also. But in order to do that we have to modify it, we have to make <code>Progress</code> know about <code>Music</code> and <code>File</code>. If our design would respect OCP, we would not need to touch <code>File</code> or <code>Progress</code>. We could just simply reuse the existing <code>Progress</code> and apply it to <code>Music</code>.</p>
    <hr>
    <h2>Solution 1: Take Advantage of the Dynamic Nature of PHP</h2>
    <p>Dynamically typed languages have the advantages of guessing the types of objects at runtime. This allows us to remove the typehint from <code>Progress</code>‘ constructor and the code will still work.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $file;&#x000A;    &#x000A;    	function __construct($file) {&#x000A;    		$this-&gt;file = $file;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;file-&gt;sent * 100 / $this-&gt;file-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    } </pre>
    <p>Now we can throw anything at <code>Progress</code>. And by anything, I mean literally anything:</p>
    <pre>class Music {&#x000A;    &#x000A;    	public $length;&#x000A;    	public $sent;&#x000A;    &#x000A;    	public $artist;&#x000A;    	public $album;&#x000A;    	public $releaseDate;&#x000A;    &#x000A;    	function getAlbumCoverFile() {&#x000A;    		return 'Images/Covers/' . $this-&gt;artist . '/' . $this-&gt;album . '.png';&#x000A;    	}&#x000A;    } </pre>
    <p>And a <code>Music</code> class like the one above will work just fine. We can test it easily with a very similar test to <code>File</code>.</p>
    <pre>function testItCanGetTheProgressOfAMusicStreamAsAPercent() {&#x000A;    	$music = new Music();&#x000A;    	$music-&gt;length = 200;&#x000A;    	$music-&gt;sent = 100;&#x000A;    &#x000A;    	$progress = new Progress($music);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>So basically, any measurable content can be used with the <code>Progress</code> class. Maybe we should express this in code by changing the variable’s name also:</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $measurableContent;&#x000A;    &#x000A;    	function __construct($measurableContent) {&#x000A;    		$this-&gt;measurableContent = $measurableContent;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;measurableContent-&gt;sent * 100 / $this-&gt;measurableContent-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    } </pre>
    <p>Good, but we have a huge problem with this approach. When we had <code>File</code> specified as a typehint, we were positive about what our class can handle. It was explicit and if something else came in, a nice error told us so.</p>
    <pre>Argument 1 passed to Progress::__construct()&#x000A;    must be an instance of File,&#x000A;    instance of Music given.</pre>
    <p>But without the typehint, we must rely on the fact that whatever comes in will have two public variables of some exact names like “<code>length</code>” and “<code>sent</code>“. Otherwise we will have a refused bequest.</p>
    <blockquote><p>Refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class. ~Source Wikipedia.</p></blockquote>
    <p>This is one of the <em>code smells</em> presented in much more detail in the <a href="https://tutsplus.com/course/detecting-code-smells/" rel="nofollow external" class="bo">Detecting Code Smells</a> premium course. In short, we do not want to end up trying to call methods or access fields on objects that do not conform to our contract. When we had a typehint, the contract was specified by it. The fields and methods of the <code>File</code> class. Now that we have nothing, we can send in anything, even a string and it would result in an ugly error.</p>
    <pre>function testItFailsWithAParameterThatDoesNotRespectTheImplicitContract() {&#x000A;    	$progress = new Progress('some string');&#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>A test like this, where we send in a simple string, will produce a refused bequest:</p>
    <pre>Trying to get property of non-object.</pre>
    <p>While the end result is the same in both cases, meaning the code breaks, the first one produced a nice message. This one, however, is very obscure. There is no way of knowing what the variable is – a string in our case – and what properties were looked for and not found. It is difficult to debug and to solve the problem. A programmer needs to open the <code>Progress</code> class and read it and understand it. The contract, in this case, when we do not explicitly specify the typehint, is defined by the behavior of <code>Progress</code>. It is an implicit contract, known only to <code>Progress</code>. In our example, it is defined by the access to the two fields, <code>sent</code> and <code>length</code>, in the <code>getAsPercent()</code> method. In real life the implicit contract can be very complex and hard to discover by just looking for a few seconds at the class.</p>
    <p>This solution is recommended only if none of the other suggestions below can easily be implemented or if they would inflict serious architectural changes that do not justify the effort.</p>
    <hr>
    <h2>Solution 2: Use the Strategy Design Pattern</h2>
    <p>This is the most common and probably the most appropriate solution to respect OCP. It is simple and effective.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/strategy.png" alt="strategy" width="600" height="294" style="max-width: 100%; height: auto;"><br> <p>The Strategy Pattern simply introduces the use of an interface. An interface is a special type of entity in Object Oriented Programming (OOP) which defines a contract between a client and a server class. Both classes will adhere to the contract to ensure the expected behavior. There may be several, unrelated, server classes that respect the same contract thus being capable of serving the same client class.</p>
    <pre>interface Measurable {&#x000A;    	function getLength();&#x000A;    	function getSent();&#x000A;    }</pre>
    <p>In an interface we can define only behavior. That is why instead of directly using public variables we will have to think about using getters and setters. Adapting the other classes will not be difficult at this point. Our IDE can do most of the job.</p>
    <pre>function testItCanGetTheProgressOfAFileAsAPercent() {&#x000A;    	$file = new File();&#x000A;    	$file-&gt;setLength(200);&#x000A;    	$file-&gt;setSent(100);&#x000A;    &#x000A;    	$progress = new Progress($file);&#x000A;    &#x000A;    	$this-&gt;assertEquals(50, $progress-&gt;getAsPercent());&#x000A;    }</pre>
    <p>As usual, we start with our tests. We will need to use setters to set the values. If considered mandatory, these setters may also be defined in the <code>Measurable</code> interface. However, be careful what you put there. The interface is to define the contract between the client class <code>Progress</code> and the different server classes like <code>File</code> and <code>Music</code>. Does <code>Progress</code> need to set the values? Probably not. So the setters are highly unlikely to be needed to be defined in the interface. Also, if you would define the setters there, you would force all of the server classes to implement setters. For some of them, it may be logical to have setters, but others may behave totally differently. What if we want to use our <code>Progress</code> class to show the temperature of our oven? The <code>OvenTemperature</code> class may be initialized with the values in the constructor, or obtain the information from a third class. Who knows? To have setters on that class would be odd.</p>
    <pre>class File implements Measurable {&#x000A;    &#x000A;    	private $length;&#x000A;    	private $sent;&#x000A;    &#x000A;    	public $filename;&#x000A;    	public $owner;&#x000A;    &#x000A;    	function setLength($length) {&#x000A;    		$this-&gt;length = $length;&#x000A;    	}&#x000A;    &#x000A;    	function getLength() {&#x000A;    		return $this-&gt;length;&#x000A;    	}&#x000A;    &#x000A;    	function setSent($sent) {&#x000A;    		$this-&gt;sent = $sent;&#x000A;    	}&#x000A;    &#x000A;    	function getSent() {&#x000A;    		return $this-&gt;sent;&#x000A;    	}&#x000A;    &#x000A;    	function getRelativePath() {&#x000A;    		return dirname($this-&gt;filename);&#x000A;    	}&#x000A;    &#x000A;    	function getFullPath() {&#x000A;    		return realpath($this-&gt;getRelativePath());&#x000A;    	}&#x000A;    &#x000A;    }</pre>
    <p>The <code>File</code> class is modified slightly to accommodate the requirements above. It now implements the <code>Measurable</code> interface and has setters and getters for the fields we are interested in. <code>Music</code> is very similar, you can check its content in the attached source code. We are almost done.</p>
    <pre>class Progress {&#x000A;    &#x000A;    	private $measurableContent;&#x000A;    &#x000A;    	function __construct(Measurable $measurableContent) {&#x000A;    		$this-&gt;measurableContent = $measurableContent;&#x000A;    	}&#x000A;    &#x000A;    	function getAsPercent() {&#x000A;    		return $this-&gt;measurableContent-&gt;getSent() * 100 / $this-&gt;measurableContent-&gt;getLength();&#x000A;    	}&#x000A;    &#x000A;    } </pre>
    <p><code>Progress</code> also needed a small update. We can now specify a type, using typehinting, in the constructor. The expected type is <code>Measurable</code>. Now we have an explicit contract. <code>Progress</code> can be sure the accessed methods will be always present because they are defined in the <code>Measurable</code> interface. <code>File</code> and <code>Music</code> can also be sure they can provide all that is needed for <code>Progress</code> by simply implementing all the methods on the interface, a requirement when a class implements an interface.</p>
    <p>This design pattern is explained in greater detail in the <a href="https://tutsplus.com/course/agile-design-patterns/" rel="nofollow external" class="bo">Agile Design Patterns</a> course.</p>
    <h3>A Note on Interface Naming</h3>
    <p>People tend to name interfaces with a capital <code>I</code> in front of them, or with the word “<code>Interface</code>” attached at the end, like <code>IFile</code> or <code>FileInterface</code>. This is an old-style notation imposed by some outdated standards. We are so much past the Hungarian notations or the need to specify the type of a variable or object in its name in order to easier identify it. IDEs identify anything in a split second for us. This allows us to concentrate on what we actually want to abstract.</p>
    <p>Interfaces belong to their clients. Yes. When you want to name an interface you must think of the client and forget about the implementation. When we named our interface Measurable we did so thinking about Progress. If I would be a progress, what would I need to be able to provide the percent? The answer is simple, something we can measure. Thus the name Measurable.</p>
    <p>Another reason is that the implementation can be from various domains. In our case, there are files and music. But we may very well reuse our <code>Progress</code> in a racing simulator. In that case, the measured classes would be Speed, Fuel, etc. Nice, isn’t it?</p>
    <hr>
    <h2>Solution 3: Use the Template Method Design Pattern</h2>
    <p>The Template Method design pattern is very similar to the strategy, but instead of an interface it uses an abstract class. It is recommended to use a Template Method pattern when we have a client very specific to our application, with reduced reusability and when the server classes have common behavior.</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/template_method.png" alt="template_method" width="600" height="294" style="max-width: 100%; height: auto;"><br> <p>This design pattern is explained in greater detail in the <a href="https://tutsplus.com/course/agile-design-patterns/" rel="nofollow external" class="bo">Agile Design Patterns</a> course.</p>
    <hr>
    <h2>A Higher Level View</h2>
    <p>So, how is all of this affecting our high level architecture?</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesign.png" alt="HighLevelDesign" width="600" height="388" style="max-width: 100%; height: auto;"><br> <p>If the image above represents the current architecture of our application, adding a new module with five new classes (the blue ones) should affect our design in a moderate way (red class).</p>  <img src="http://cdn.tutsplus.com/net/uploads/2014/01/HighLevelDesignWithNewClasses.png" alt="HighLevelDesignWithNewClasses" width="600" height="410" style="max-width: 100%; height: auto;"><br> <p>In most systems you can’t expect absolutely no effect on the existing code when new classes are introduced. However, respecting the Open/Closed Principle will considerably reduce the classes and modules that require constant change.</p>
    <p>As with any other principle, try not to think about everything from before. If you do so, you will end up with an interface for each of your classes. Such a design will be hard to maintain and understand. Usually the safest way to go is to think about the possibilities and if you can determine whether there will be other types of server classes. Many times you can easily imagine a new feature or you can find one on the project’s backlog that will produce another server class. In those cases, add the interface from the beginning. If you can not determine, or if you are unsure – most of the time – simply omit it. Let the next programmer, or maybe even yourself, to add the interface when you need a second implementation.</p>
    <hr>
    <h2>Final Thoughts</h2>
    <p>If you follow your discipline and add interfaces as soon as a second server is needed, modifications will be few and easy. Remember, if code required changes once, there is a high possibility it will require change again. When that possibility turns into reality, OCP will save you a lot of time and effort.</p>
    <p>Thank you for reading.</p>
    </div>
]]>
</Body>
<Summary>Single Responsibility (SRP), Open/Closed (OCP), Liskov’s Substitution, Interface Segregation, and Dependency Inversion. Five agile principles that should guide you every time you need to write...</Summary>
<Website>http://feedproxy.google.com/~r/nettuts/~3/aH8si1mNSHI/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/40415/guest@my.umbc.edu/c801f99c8563903d1c1241dd81e3f632/api/pixel</TrackingUrl>
<Tag>css</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>open-closed-principle</Tag>
<Tag>php</Tag>
<Tag>solid-principles</Tag>
<Tag>sql</Tag>
<Tag>tutorials</Tag>
<Tag>wed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 15:09:07 -0500</PostedAt>
<EditAt>Mon, 20 Jan 2014 15:09:07 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="false" id="122871" important="false" status="posted" url="https://my3.my.umbc.edu/posts/122871">
<Title>Celebrating MLK Day</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>As we celebrate Martin Luther King Jr. Day, check out UMBC’s online exhibit “<a href="http://www.umbc.edu/cadvc/foralltheworld/index.php" rel="nofollow external" class="bo">For All the World to See,</a>” which focuses on the civil rights movement.</p>
    <blockquote><p>For All the World to See: Visual Culture and the Struggle for Civil Rights is organized by the Center for Art, Design and Visual Culture, University of Maryland, Baltimore County in partnership with the Smithsonian National Museum of African American History and Culture. Through a host of media—including photographs, television and film, magazines, newspapers, posters, books, and pamphlets—the project explores the historic role of visual culture in shaping, influencing, and transforming the fight for racial equality and justice in the United States from the late-1940s to the mid-1970s. <em>For All the World to See</em> includes a traveling exhibition, website, online film festival, and richly illustrated companion book.</p></blockquote>
    <p>If you’re in Texas, the exhibit will be coming your way on January 28. Be sure to <a href="http://www.umbc.edu/blogs/foralltheworld/" rel="nofollow external" class="bo">see if it’s making a stop in a town near you</a>!</p>
    <p><em>For more information, <a href="http://umbcmagazine.wordpress.com/umbc-magazine-fall-2012/staging-the-struggle-2/" rel="nofollow external" class="bo">read our story about the exhibit</a> from an issue of the UMBC Magazine.</em></p>
    </div>
]]>
</Body>
<Summary>As we celebrate Martin Luther King Jr. Day, check out UMBC’s online exhibit “For All the World to See,” which focuses on the civil rights movement.    For All the World to See: Visual Culture and...</Summary>
<Website>https://umbc.edu/stories/celebrating-mlk-day/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/122871/guest@my.umbc.edu/483aeb825a19999918ae2518539da59f/api/pixel</TrackingUrl>
<Tag>alumni</Tag>
<Tag>civil-rights</Tag>
<Tag>civil-rights-movement</Tag>
<Tag>for-all-the-world-to-see</Tag>
<Tag>martin-luther-king</Tag>
<Tag>martin-luther-king-jr</Tag>
<Tag>mlk</Tag>
<Tag>mlk-day</Tag>
<Tag>umbc</Tag>
<Tag>university-of-maryland-baltimore-county</Tag>
<Group token="umbc-news-magazine">UMBC News &amp;amp; Magazine</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news-magazine</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/original.png?1748556657</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/large.png?1748556657</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/medium.png?1748556657</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/small.png?1748556657</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxsmall.png?1748556657</AvatarUrl>
<Sponsor>UMBC News &amp; Magazine</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Mon, 20 Jan 2014 14:00:43 -0500</PostedAt>
</NewsItem>

</News>
